Add pdfBackground constructor property (#4207)

This commit is contained in:
Caleb Meredith 2024-09-06 07:31:43 -04:00 committed by GitHub
parent fc32e0bd3f
commit 7ee54810d4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 46 additions and 4 deletions

View File

@ -40,6 +40,7 @@ where the overall height is the `pageHeight` multiplied by the number of `pages`
| [options.page] | <code>number</code> | <code>0</code> | Page number to start extracting from for multi-page input (GIF, WebP, TIFF), zero based. |
| [options.subifd] | <code>number</code> | <code>-1</code> | subIFD (Sub Image File Directory) to extract for OME-TIFF, defaults to main image. |
| [options.level] | <code>number</code> | <code>0</code> | level to extract from a multi-level input (OpenSlide), zero based. |
| [options.pdfBackground] | <code>string</code> \| <code>Object</code> | | Background color to use when PDF is partially transparent. Parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. Requires the use of a globally-installed libvips compiled with support for PDFium, poppler-glib, ImageMagick, or GraphicsMagick. |
| [options.animated] | <code>boolean</code> | <code>false</code> | Set to `true` to read all frames/pages of an animated image (GIF, WebP, TIFF), equivalent of setting `pages` to `-1`. |
| [options.raw] | <code>Object</code> | | describes raw pixel input image data. See `raw()` for pixel ordering. |
| [options.raw.width] | <code>number</code> | | integral number of pixels wide. |

File diff suppressed because one or more lines are too long

View File

@ -139,6 +139,7 @@ const debuglog = util.debuglog('sharp');
* @param {number} [options.page=0] - Page number to start extracting from for multi-page input (GIF, WebP, TIFF), zero based.
* @param {number} [options.subifd=-1] - subIFD (Sub Image File Directory) to extract for OME-TIFF, defaults to main image.
* @param {number} [options.level=0] - level to extract from a multi-level input (OpenSlide), zero based.
* @param {string|Object} [options.pdfBackground] - Background color to use when PDF is partially transparent. Parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. Requires the use of a globally-installed libvips compiled with support for PDFium, poppler-glib, ImageMagick, or GraphicsMagick.
* @param {boolean} [options.animated=false] - Set to `true` to read all frames/pages of an animated image (GIF, WebP, TIFF), equivalent of setting `pages` to `-1`.
* @param {Object} [options.raw] - describes raw pixel input image data. See `raw()` for pixel ordering.
* @param {number} [options.raw.width] - integral number of pixels wide.
@ -348,6 +349,7 @@ const Sharp = function (input, options) {
timeoutSeconds: 0,
linearA: [],
linearB: [],
pdfBackground: [255, 255, 255, 255],
// Function to notify of libvips warnings
debuglog: warning => {
this.emit('warning', warning);

2
lib/index.d.ts vendored
View File

@ -935,6 +935,8 @@ declare namespace sharp {
subifd?: number | undefined;
/** Level to extract from a multi-level input (OpenSlide), zero based. (optional, default 0) */
level?: number | undefined;
/** Background color to use when PDF is partially transparent. Requires the use of a globally-installed libvips compiled with support for PDFium, poppler-glib, ImageMagick, or GraphicsMagick. */
pdfBackground?: Color | undefined;
/** Set to `true` to read all frames/pages of an animated image (equivalent of setting `pages` to `-1`). (optional, default false) */
animated?: boolean | undefined;
/** Describes raw pixel input image data. See raw() for pixel ordering. */

View File

@ -24,8 +24,8 @@ const align = {
* @private
*/
function _inputOptionsFromObject (obj) {
const { raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd } = obj;
return [raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd].some(is.defined)
const { raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd, pdfBackground } = obj;
return [raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd, pdfBackground].some(is.defined)
? { raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd }
: undefined;
}
@ -222,6 +222,10 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
throw is.invalidParameterError('subifd', 'integer between -1 and 100000', inputOptions.subifd);
}
}
// PDF background color
if (is.defined(inputOptions.pdfBackground)) {
this._setBackgroundColourOption('pdfBackground', inputOptions.pdfBackground);
}
// Create new image
if (is.defined(inputOptions.create)) {
if (

View File

@ -109,6 +109,10 @@ namespace sharp {
if (HasAttr(input, "subifd")) {
descriptor->subifd = AttrAsInt32(input, "subifd");
}
// // PDF background color
if (HasAttr(input, "pdfBackground")) {
descriptor->pdfBackground = AttrAsVectorOfDouble(input, "pdfBackground");
}
// Create new image
if (HasAttr(input, "createChannels")) {
descriptor->createChannels = AttrAsUint32(input, "createChannels");
@ -402,6 +406,9 @@ namespace sharp {
if (imageType == ImageType::TIFF) {
option->set("subifd", descriptor->subifd);
}
if (imageType == ImageType::PDF) {
option->set("background", descriptor->pdfBackground);
}
image = VImage::new_from_buffer(descriptor->buffer, descriptor->bufferLength, nullptr, option);
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
image = SetDensity(image, descriptor->density);
@ -506,6 +513,9 @@ namespace sharp {
if (imageType == ImageType::TIFF) {
option->set("subifd", descriptor->subifd);
}
if (imageType == ImageType::PDF) {
option->set("background", descriptor->pdfBackground);
}
image = VImage::new_from_file(descriptor->file.data(), option);
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
image = SetDensity(image, descriptor->density);

View File

@ -74,6 +74,7 @@ namespace sharp {
int textSpacing;
VipsTextWrap textWrap;
int textAutofitDpi;
std::vector<double> pdfBackground;
InputDescriptor():
buffer(nullptr),
@ -108,7 +109,8 @@ namespace sharp {
textRgba(false),
textSpacing(0),
textWrap(VIPS_TEXT_WRAP_WORD),
textAutofitDpi(0) {}
textAutofitDpi(0),
pdfBackground{ 255.0, 255.0, 255.0, 255.0 } {}
};
// Convenience methods to access the attributes of a Napi::Object

View File

@ -893,6 +893,27 @@ describe('Input/output', function () {
sharp({ subifd: 1.2 });
}, /Expected integer between -1 and 100000 for subifd but received 1.2 of type number/);
});
it('Valid pdfBackground property (string)', function () {
sharp({ pdfBackground: '#00ff00' });
});
it('Valid pdfBackground property (object)', function () {
sharp({ pdfBackground: { r: 0, g: 255, b: 0 } });
});
it('Invalid pdfBackground property (string) throws', function () {
assert.throws(function () {
sharp({ pdfBackground: '00ff00' });
}, /Unable to parse color from string/);
});
it('Invalid pdfBackground property (number) throws', function () {
assert.throws(function () {
sharp({ pdfBackground: 255 });
}, /Expected object or string for background/);
});
it('Invalid pdfBackground property (object)', function () {
assert.throws(function () {
sharp({ pdfBackground: { red: 0, green: 255, blue: 0 } });
}, /Unable to parse color from object/);
});
});
it('Fails when writing to missing directory', async () => {