diff --git a/app/assets/javascripts/discourse/app/lib/media-optimization-utils.js b/app/assets/javascripts/discourse/app/lib/media-optimization-utils.js
index b67424f4c46..2d18cbf98fe 100644
--- a/app/assets/javascripts/discourse/app/lib/media-optimization-utils.js
+++ b/app/assets/javascripts/discourse/app/lib/media-optimization-utils.js
@@ -1,12 +1,10 @@
import { Promise } from "rsvp";
-export async function fileToImageData(file) {
- let drawable, err;
-
- // Chrome and Firefox use a native method to do Image -> Bitmap Array (it happens of the main thread!)
- // Safari uses the `` element due to https://bugs.webkit.org/show_bug.cgi?id=182424
+// Chrome and Firefox use a native method to do Image -> Bitmap Array (it happens of the main thread!)
+// Safari uses the `` element due to https://bugs.webkit.org/show_bug.cgi?id=182424
+async function fileToDrawable(file) {
if ("createImageBitmap" in self) {
- drawable = await createImageBitmap(file);
+ return await createImageBitmap(file);
} else {
const url = URL.createObjectURL(file);
const img = new Image();
@@ -26,38 +24,55 @@ export async function fileToImageData(file) {
// Always await loaded, as we may have bailed due to the Safari bug above.
await loaded;
-
- drawable = img;
+ return img;
}
+}
+function drawableToimageData(drawable) {
const width = drawable.width,
height = drawable.height,
sx = 0,
sy = 0,
sw = width,
sh = height;
+
// Make canvas same size as image
const canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
+
// Draw image onto canvas
const ctx = canvas.getContext("2d");
if (!ctx) {
- err = "Could not create canvas context";
+ throw "Could not create canvas context";
}
ctx.drawImage(drawable, sx, sy, sw, sh, 0, 0, width, height);
const imageData = ctx.getImageData(0, 0, width, height);
canvas.remove();
+ return imageData;
+}
- // potentially transparent
- if (/(\.|\/)(png|webp)$/i.test(file.type)) {
- for (let i = 0; i < imageData.data.length; i += 4) {
- if (imageData.data[i + 3] < 255) {
- err = "Image has transparent pixels, won't convert to JPEG!";
- break;
- }
+function isTransparent(type, imageData) {
+ if (!/(\.|\/)(png|webp)$/i.test(type)) {
+ return false;
+ }
+
+ for (let i = 0; i < imageData.data.length; i += 4) {
+ if (imageData.data[i + 3] < 255) {
+ return true;
}
}
- return { imageData, width, height, err };
+ return false;
+}
+
+export async function fileToImageData(file) {
+ const drawable = await fileToDrawable(file);
+ const imageData = drawableToimageData(drawable);
+
+ if (isTransparent(file.type, imageData)) {
+ throw "Image has transparent pixels, won't convert to JPEG!";
+ }
+
+ return imageData;
}
diff --git a/app/assets/javascripts/discourse/app/services/media-optimization-worker.js b/app/assets/javascripts/discourse/app/services/media-optimization-worker.js
index 24069246fab..f108061ad7b 100644
--- a/app/assets/javascripts/discourse/app/services/media-optimization-worker.js
+++ b/app/assets/javascripts/discourse/app/services/media-optimization-worker.js
@@ -54,10 +54,11 @@ export default class MediaOptimizationWorkerService extends Service {
this.currentComposerUploadData = data;
this.currentPromiseResolver = resolve;
- const { imageData, width, height, err } = await fileToImageData(file);
-
- if (err) {
- this.logIfDebug(err);
+ let imageData;
+ try {
+ imageData = await fileToImageData(file);
+ } catch (error) {
+ this.logIfDebug(error);
return resolve(data);
}
@@ -66,8 +67,8 @@ export default class MediaOptimizationWorkerService extends Service {
type: "compress",
file: imageData.data.buffer,
fileName: file.name,
- width: width,
- height: height,
+ width: imageData.width,
+ height: imageData.height,
settings: {
mozjpeg_script: getURLWithCDN(
"/javascripts/squoosh/mozjpeg_enc.js"
@@ -102,8 +103,6 @@ export default class MediaOptimizationWorkerService extends Service {
registerMessageHandler() {
this.worker.onmessage = (e) => {
- this.logIfDebug("Main: Message received from worker script");
- this.logIfDebug(e);
switch (e.data.type) {
case "file":
let optimizedFile = new File([e.data.file], `${e.data.fileName}`, {
diff --git a/public/javascripts/media-optimization-worker.js b/public/javascripts/media-optimization-worker.js
index 7bbdf137bd5..7bd196854c2 100644
--- a/public/javascripts/media-optimization-worker.js
+++ b/public/javascripts/media-optimization-worker.js
@@ -81,6 +81,7 @@ async function optimize(imageData, fileName, width, height, settings) {
).data;
width = target_dimensions.width;
height = target_dimensions.height;
+ logIfDebug(`Worker post resizing file: ${maybeResized.byteLength}`);
} catch (error) {
console.error(`Resize failed: ${error}`);
maybeResized = imageData;