mirror of
https://github.com/lovell/sharp.git
synced 2025-12-19 07:15:08 +01:00
Expose density metadata; set density of images from vector input
This commit is contained in:
@@ -176,6 +176,30 @@ namespace sharp {
|
||||
SetExifOrientation(image, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
Does this image have a non-default density?
|
||||
*/
|
||||
bool HasDensity(VImage image) {
|
||||
return image.xres() > 1.0;
|
||||
}
|
||||
|
||||
/*
|
||||
Get pixels/mm resolution as pixels/inch density.
|
||||
*/
|
||||
int GetDensity(VImage image) {
|
||||
return static_cast<int>(round(image.xres() * 25.4));
|
||||
}
|
||||
|
||||
/*
|
||||
Set pixels/mm resolution based on a pixels/inch density.
|
||||
*/
|
||||
void SetDensity(VImage image, const int density) {
|
||||
const double pixelsPerMm = static_cast<double>(density) / 25.4;
|
||||
image.set("Xres", pixelsPerMm);
|
||||
image.set("Yres", pixelsPerMm);
|
||||
image.set(VIPS_META_RESOLUTION_UNIT, "in");
|
||||
}
|
||||
|
||||
/*
|
||||
Called when a Buffer undergoes GC, required to support mixed runtime libraries in Windows
|
||||
*/
|
||||
|
||||
15
src/common.h
15
src/common.h
@@ -77,6 +77,21 @@ namespace sharp {
|
||||
*/
|
||||
void RemoveExifOrientation(VImage image);
|
||||
|
||||
/*
|
||||
Does this image have a non-default density?
|
||||
*/
|
||||
bool HasDensity(VImage image);
|
||||
|
||||
/*
|
||||
Get pixels/mm resolution as pixels/inch density.
|
||||
*/
|
||||
int GetDensity(VImage image);
|
||||
|
||||
/*
|
||||
Set pixels/mm resolution based on a pixels/inch density.
|
||||
*/
|
||||
void SetDensity(VImage image, const int density);
|
||||
|
||||
/*
|
||||
Called when a Buffer undergoes GC, required to support mixed runtime libraries in Windows
|
||||
*/
|
||||
|
||||
@@ -38,6 +38,8 @@ using sharp::DetermineImageType;
|
||||
using sharp::HasProfile;
|
||||
using sharp::HasAlpha;
|
||||
using sharp::ExifOrientation;
|
||||
using sharp::HasDensity;
|
||||
using sharp::GetDensity;
|
||||
using sharp::FreeCallback;
|
||||
using sharp::counterQueue;
|
||||
|
||||
@@ -52,6 +54,7 @@ struct MetadataBaton {
|
||||
int height;
|
||||
std::string space;
|
||||
int channels;
|
||||
int density;
|
||||
bool hasProfile;
|
||||
bool hasAlpha;
|
||||
int orientation;
|
||||
@@ -63,6 +66,7 @@ struct MetadataBaton {
|
||||
|
||||
MetadataBaton():
|
||||
bufferInLength(0),
|
||||
density(0),
|
||||
orientation(0),
|
||||
exifLength(0),
|
||||
iccLength(0) {}
|
||||
@@ -120,6 +124,9 @@ class MetadataWorker : public AsyncWorker {
|
||||
baton->height = image.height();
|
||||
baton->space = vips_enum_nick(VIPS_TYPE_INTERPRETATION, image.interpretation());
|
||||
baton->channels = image.bands();
|
||||
if (HasDensity(image)) {
|
||||
baton->density = GetDensity(image);
|
||||
}
|
||||
baton->hasProfile = HasProfile(image);
|
||||
// Derived attributes
|
||||
baton->hasAlpha = HasAlpha(image);
|
||||
@@ -161,6 +168,9 @@ class MetadataWorker : public AsyncWorker {
|
||||
Set(info, New("height").ToLocalChecked(), New<Number>(baton->height));
|
||||
Set(info, New("space").ToLocalChecked(), New<String>(baton->space).ToLocalChecked());
|
||||
Set(info, New("channels").ToLocalChecked(), New<Number>(baton->channels));
|
||||
if (baton->density > 0) {
|
||||
Set(info, New("density").ToLocalChecked(), New<Number>(baton->density));
|
||||
}
|
||||
Set(info, New("hasProfile").ToLocalChecked(), New<Boolean>(baton->hasProfile));
|
||||
Set(info, New("hasAlpha").ToLocalChecked(), New<Boolean>(baton->hasAlpha));
|
||||
if (baton->orientation > 0) {
|
||||
|
||||
@@ -169,4 +169,5 @@ namespace sharp {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sharp
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace sharp {
|
||||
* Sharpen flat and jagged areas. Use radius of -1 for fast sharpen.
|
||||
*/
|
||||
VImage Sharpen(VImage image, int const radius, double const flat, double const jagged);
|
||||
|
||||
} // namespace sharp
|
||||
|
||||
#endif // SRC_OPERATIONS_H_
|
||||
|
||||
@@ -58,6 +58,7 @@ using sharp::HasAlpha;
|
||||
using sharp::ExifOrientation;
|
||||
using sharp::SetExifOrientation;
|
||||
using sharp::RemoveExifOrientation;
|
||||
using sharp::SetDensity;
|
||||
using sharp::IsJpeg;
|
||||
using sharp::IsPng;
|
||||
using sharp::IsWebp;
|
||||
@@ -118,9 +119,12 @@ class PipelineWorker : public AsyncWorker {
|
||||
try {
|
||||
VOption *option = VImage::option()->set("access", baton->accessMethod);
|
||||
if (inputImageType == ImageType::MAGICK) {
|
||||
option->set("density", baton->density.data());
|
||||
option->set("density", std::to_string(baton->density).data());
|
||||
}
|
||||
image = VImage::new_from_buffer(baton->bufferIn, baton->bufferInLength, nullptr, option);
|
||||
if (inputImageType == ImageType::MAGICK) {
|
||||
SetDensity(image, baton->density);
|
||||
}
|
||||
} catch (...) {
|
||||
(baton->err).append("Input buffer has corrupt header");
|
||||
inputImageType = ImageType::UNKNOWN;
|
||||
@@ -136,9 +140,12 @@ class PipelineWorker : public AsyncWorker {
|
||||
try {
|
||||
VOption *option = VImage::option()->set("access", baton->accessMethod);
|
||||
if (inputImageType == ImageType::MAGICK) {
|
||||
option->set("density", baton->density.data());
|
||||
option->set("density", std::to_string(baton->density).data());
|
||||
}
|
||||
image = VImage::new_from_file(baton->fileIn.data(), option);
|
||||
if (inputImageType == ImageType::MAGICK) {
|
||||
SetDensity(image, baton->density);
|
||||
}
|
||||
} catch (...) {
|
||||
(baton->err).append("Input file has corrupt header");
|
||||
inputImageType = ImageType::UNKNOWN;
|
||||
@@ -921,7 +928,7 @@ NAN_METHOD(pipeline) {
|
||||
// Limit input images to a given number of pixels, where pixels = width * height
|
||||
baton->limitInputPixels = attrAs<int32_t>(options, "limitInputPixels");
|
||||
// Density/DPI at which to load vector images via libmagick
|
||||
baton->density = attrAsStr(options, "density");
|
||||
baton->density = attrAs<int32_t>(options, "density");
|
||||
// Raw pixel input
|
||||
baton->rawWidth = attrAs<int32_t>(options, "rawWidth");
|
||||
baton->rawHeight = attrAs<int32_t>(options, "rawHeight");
|
||||
|
||||
@@ -19,7 +19,7 @@ struct PipelineBaton {
|
||||
size_t bufferInLength;
|
||||
std::string iccProfilePath;
|
||||
int limitInputPixels;
|
||||
std::string density;
|
||||
int density;
|
||||
int rawWidth;
|
||||
int rawHeight;
|
||||
int rawChannels;
|
||||
@@ -79,7 +79,7 @@ struct PipelineBaton {
|
||||
PipelineBaton():
|
||||
bufferInLength(0),
|
||||
limitInputPixels(0),
|
||||
density(""),
|
||||
density(72),
|
||||
rawWidth(0),
|
||||
rawHeight(0),
|
||||
rawChannels(0),
|
||||
|
||||
Reference in New Issue
Block a user