From bf5f06285b40cb2f7f827168388f2ff324c4ba6a Mon Sep 17 00:00:00 2001 From: Shaho Awier Date: Sun, 20 Dec 2020 06:19:34 +0100 Subject: [PATCH] Adding conditional withMetaData on sharp (#49) * Added flag for sharp withMetaData * Added changes to readme --- README.md | 1 + src/index.js | 42 ++++++++++++++++++++++++------------------ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index e8fa1df..d0d8f7c 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,7 @@ try { - __jpegOptions__ [0-100] - Example: { force:true, quality:100 } - __fit__ [string] - method by which the image should fit the width/height. Default = contain ([details](https://sharp.pixelplumbing.com/api-resize)) - __failOnError__ [boolean] - Set to false to avoid read problems for images from some phones (i.e Samsung) in the sharp lib. Default = true ([details](https://github.com/lovell/sharp/issues/1578)) + - __withMetaData__ [boolean] - Keep metadata in the thumbnail (will increase file size) ### Examples ```js diff --git a/src/index.js b/src/index.js index 00fa279..b0bce22 100644 --- a/src/index.js +++ b/src/index.js @@ -12,10 +12,10 @@ const { fail } = require('assert'); const PERCENTAGE = 10; const RESPONSE_TYPE = 'buffer'; -const fromBase64 = async (source, percentage, width, height, responseType, jpegOptions, fit, failOnError) => { +const fromBase64 = async (source, percentage, width, height, responseType, jpegOptions, fit, failOnError, withMetaData) => { const imageBuffer = Buffer.from(source, 'base64'); const dimensions = getDimensions(imageBuffer, percentage, { width, height }); - const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError); + const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError, withMetaData); if (responseType === 'base64') { return thumbnailBuffer.toString('base64'); @@ -24,12 +24,12 @@ const fromBase64 = async (source, percentage, width, height, responseType, jpegO return thumbnailBuffer; }; -const fromUri = async (source, percentage, width, height, responseType, jpegOptions, fit, failOnError) => { +const fromUri = async (source, percentage, width, height, responseType, jpegOptions, fit, failOnError, withMetaData) => { const response = await axios.get(source.uri, { responseType: 'arraybuffer' }); const imageBuffer = Buffer.from(response.data, 'binary'); const dimensions = getDimensions(imageBuffer, percentage, { width, height }); - const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError); + const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError, withMetaData); if (responseType === 'base64') { @@ -39,11 +39,11 @@ const fromUri = async (source, percentage, width, height, responseType, jpegOpti return thumbnailBuffer; }; -const fromPath = async (source, percentage, width, height, responseType, jpegOptions, fit, failOnError) => { +const fromPath = async (source, percentage, width, height, responseType, jpegOptions, fit, failOnError, withMetaData) => { const imageBuffer = fs.readFileSync(source); const dimensions = getDimensions(imageBuffer, percentage, { width, height }); - const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError); + const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError, withMetaData); if (responseType === 'base64') { return thumbnailBuffer.toString('base64'); @@ -52,10 +52,10 @@ const fromPath = async (source, percentage, width, height, responseType, jpegOpt return thumbnailBuffer; }; -const fromReadStream = async (source, percentage, width, height, responseType, jpegOptions, fit, failOnError) => { +const fromReadStream = async (source, percentage, width, height, responseType, jpegOptions, fit, failOnError, withMetaData) => { const imageBuffer = await util.streamToBuffer(source); const dimensions = getDimensions(imageBuffer, percentage, { width, height }); - const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError); + const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError, withMetaData); if (responseType === 'base64') { return thumbnailBuffer.toString('base64'); @@ -64,11 +64,11 @@ const fromReadStream = async (source, percentage, width, height, responseType, j return thumbnailBuffer; }; -const fromBuffer = async (source, percentage, width, height, responseType, jpegOptions, fit, failOnError) => { +const fromBuffer = async (source, percentage, width, height, responseType, jpegOptions, fit, failOnError, withMetaData) => { const imageBuffer = source; const dimensions = getDimensions(imageBuffer, percentage, { width, height }); - const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError); + const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError, withMetaData); if (responseType === 'base64') { return thumbnailBuffer.toString('base64'); @@ -85,24 +85,25 @@ module.exports = async (source, options) => { const jpegOptions = options && options.jpegOptions ? options.jpegOptions : undefined; const fit = options && options.fit ? options.fit : undefined; const failOnError = options && typeof(options.failOnError) !== 'undefined' ? options.failOnError : true; + const withMetaData = options && typeof(options.withMetaData) !== 'undefined' ? options.withMetaData : false; try { switch (typeof source) { case 'object': let response; if (source instanceof fs.ReadStream || source instanceof stream.PassThrough) { - response = await fromReadStream(source, percentage, width, height, responseType, jpegOptions, fit, failOnError); + response = await fromReadStream(source, percentage, width, height, responseType, jpegOptions, fit, failOnError, withMetaData); } else if (source instanceof Buffer) { - response = await fromBuffer(source, percentage, width, height, responseType, jpegOptions, fit, failOnError); + response = await fromBuffer(source, percentage, width, height, responseType, jpegOptions, fit, failOnError, withMetaData); } else { - response = await fromUri(source, percentage, width, height, responseType, jpegOptions, fit, failOnError); + response = await fromUri(source, percentage, width, height, responseType, jpegOptions, fit, failOnError, withMetaData); } return response; case 'string': if (validator.isBase64(source)) { - return await fromBase64(source, percentage, width, height, responseType, jpegOptions, fit, failOnError); + return await fromBase64(source, percentage, width, height, responseType, jpegOptions, fit, failOnError, withMetaData); } else { - return await fromPath(source, percentage, width, height, responseType, jpegOptions, fit, failOnError); + return await fromPath(source, percentage, width, height, responseType, jpegOptions, fit, failOnError, withMetaData); } default: throw new Error('unsupported source type'); @@ -125,13 +126,18 @@ const getDimensions = (imageBuffer, percentageOfImage, dimensions) => { return { width, height }; } -const sharpResize = (imageBuffer, dimensions, jpegOptions, fit, failOnError) => { +const sharpResize = (imageBuffer, dimensions, jpegOptions, fit, failOnError, withMetadata) => { return new Promise((resolve, reject) => { - sharp(imageBuffer, { failOnError }) + let result = sharp(imageBuffer, { failOnError }) .resize({ ...dimensions, withoutEnlargement: true, fit: fit ? fit : 'contain', }) - .jpeg(jpegOptions ? jpegOptions : { force: false }) + + if(withMetadata){ + result.withMetadata() + } + + result.jpeg(jpegOptions ? jpegOptions : { force: false }) .toBuffer((err, data) => { if (err) { reject(err);