From eabb8f5224afa3220ebc2008c9b328304cf12a8d Mon Sep 17 00:00:00 2001 From: memeller Date: Fri, 11 Nov 2022 23:21:42 +0100 Subject: [PATCH] PNG support Added support for resizing of PNG files. The detection methods for supported files were slightly modified to include png files. Previously "data:iamge/jpeg" was hardcoded (shrunked.js, ShrunkedImage.jsm), but now the image format is preserved - pngs are resized and saved as pngs, jpegs are resized and saved as jpegs. Tested for inline images and attachments, everything works under TB 102.4.2 --- api/shrunked.js | 24 ++++++++++++++---------- background.js | 2 +- compose_script.js | 13 ++++++++----- modules/ShrunkedImage.jsm | 14 +++++++++----- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/api/shrunked.js b/api/shrunked.js index f754a2d..4c3fa0a 100644 --- a/api/shrunked.js +++ b/api/shrunked.js @@ -57,14 +57,14 @@ var shrunked = class extends ExtensionCommon.ExtensionAPI { let shouldShow = false; if (target.nodeName == "IMG") { console.log("Context menu on an "); - if (target.src.startsWith("data:image/jpeg;")) { + if (imageIsAccepted(target.src)) { if (target.width > 500 || target.height > 500) { shouldShow = true; } else { console.log("Not resizing - image is too small"); } } else { - console.log("Not resizing - image is not JPEG"); + console.log("Not resizing - image is not JPEG / PNG"); } } @@ -97,10 +97,8 @@ var shrunked = class extends ExtensionCommon.ExtensionAPI { let reader = new FileReader(); reader.onloadend = function() { let dataURL = reader.result; - dataURL = - "data:image/jpeg;filename=" + - encodeURIComponent(destFile.name) + - dataURL.substring(15); + let headerIndexEnd = dataURL.indexOf(";"); + dataURL = reader.result.substring(0, headerIndexEnd) + ";filename=" + encodeURIComponent(destFile.name) + dataURL.substring(headerIndexEnd); resolve(dataURL); }; reader.readAsDataURL(destFile); @@ -129,16 +127,15 @@ var shrunked = class extends ExtensionCommon.ExtensionAPI { } let attachment = items[i].attachment; if ( - attachment.url.startsWith("data:image/jpeg;") || - /\.jpe?g$/i.test(attachment.url) + imageIsAccepted(attachment.url) ) { + indicies.push(i); } } - attachmentMenuItem.hidden = !indicies.length; if (!indicies.length) { - console.log("Not resizing - no attachments were JPEG and large enough"); + console.log("Not resizing - no attachments were JPEG/PNG and large enough"); } else if (indicies.length == 1) { attachmentMenuItem.label = localeData.localizeMessage("context.single"); } else { @@ -347,3 +344,10 @@ var shrunked = class extends ExtensionCommon.ExtensionAPI { } } }; + +function imageIsAccepted(url) { + let src = url.toLowerCase(); + let isJPEG = src.startsWith("data:image/jpeg") || src.endsWith(".jpg") || src.endsWith(".jpeg"); + let isPNG = src.startsWith("data:image/png") || src.endsWith(".png"); + return isJPEG | isPNG; +} \ No newline at end of file diff --git a/background.js b/background.js index 2410124..691ab4d 100644 --- a/background.js +++ b/background.js @@ -1,7 +1,7 @@ var tabMap = new Map(); async function shouldResize(attachment, checkSize = true) { - if (!attachment.name.toLowerCase().match(/\.jpe?g$/)) { + if (!attachment.name.toLowerCase().match(/((\.jpe?g)|(\.png))$/)) { return false; } if (!checkSize) { diff --git a/compose_script.js b/compose_script.js index cd9039a..48dedf4 100644 --- a/compose_script.js +++ b/compose_script.js @@ -58,8 +58,8 @@ async function maybeResizeInline(target) { console.log("Not resizing - image already has shrunked attribute"); return; } - if (!imageIsJPEG(target)) { - console.log("Not resizing - image is not JPEG"); + if (!imageIsAccepted(target)) { + console.log("Not resizing - image is not JPEG / PNG"); return; } if (target.width < 500 && target.height < 500) { @@ -106,8 +106,9 @@ async function maybeResizeInline(target) { let reader = new FileReader(); reader.onloadend = function() { let dataURL = reader.result; + let headerIndexEnd = dataURL.indexOf(";"); dataURL = - "data:image/jpeg;filename=" + encodeURIComponent(destFile.name) + dataURL.substring(15); + reader.result.substring(0, headerIndexEnd) + ";filename=" + encodeURIComponent(destFile.name) + dataURL.substring(headerIndexEnd); resolve(dataURL); }; reader.readAsDataURL(destFile); @@ -128,7 +129,9 @@ async function maybeResizeInline(target) { } } -function imageIsJPEG(image) { +function imageIsAccepted(image) { let src = image.src.toLowerCase(); - return src.startsWith("data:image/jpeg") || src.endsWith(".jpg"); + let isJPEG = src.startsWith("data:image/jpeg") || src.endsWith(".jpg") || src.endsWith(".jpeg"); + let isPNG = src.startsWith("data:image/png") || src.endsWith(".png"); + return isJPEG | isPNG; } diff --git a/modules/ShrunkedImage.jsm b/modules/ShrunkedImage.jsm index f5c9190..14e4c79 100644 --- a/modules/ShrunkedImage.jsm +++ b/modules/ShrunkedImage.jsm @@ -11,6 +11,7 @@ var XHTMLNS = "http://www.w3.org/1999/xhtml"; function ShrunkedImage(source, maxWidth, maxHeight, quality, options) { this.maxWidth = maxWidth; this.maxHeight = maxHeight; + this.imageFormat="image/jpeg"; this.quality = quality; this.options = { exif: true, @@ -38,7 +39,7 @@ function ShrunkedImage(source, maxWidth, maxHeight, quality, options) { if (match) { this.basename = match[1]; } else { - match = /\/([\w.-]+\.jpg)$/i.exec(this.sourceURI.spec); + match =/\/([\w.-]+\.(jpe?g|png))$/i.exec(this.sourceURI.spec); if (match) { this.basename = match[1]; } @@ -52,7 +53,10 @@ function ShrunkedImage(source, maxWidth, maxHeight, quality, options) { this.sourceURI = Services.io.newURI(URL.createObjectURL(source)); this.basename = source.name; } - + if(this.basename.endsWith(".png")) + { + this.imageFormat="image/png"; + } if (!this.sourceURI) { throw new Error("Unexpected source passed to ShrunkedImage"); } @@ -75,7 +79,7 @@ ShrunkedImage.prototype = { } let blob = await this.getBytes(canvas); - return new File([blob], this.basename, { type: "image/jpeg" }); + return new File([blob], this.basename, { type: this.imageFormat }); }, async readExifData() { try { @@ -186,8 +190,8 @@ ShrunkedImage.prototype = { reject(ex); } }, - "image/jpeg", - this.quality / 100 + this.imageFormat, + (this.imageFormat=="image/jpeg")?(this.quality / 100):null ); }); },