diff --git a/src/frontend/flask_app/static/js/image_to_png.js b/src/frontend/flask_app/static/js/image_to_png.js
new file mode 100644
index 0000000..b86c576
--- /dev/null
+++ b/src/frontend/flask_app/static/js/image_to_png.js
@@ -0,0 +1,38 @@
+/**
+ * image_to_png.js - #107: converte nel browser le immagini che il backend non ammette (es. BMP) in PNG.
+ *
+ * Cosa fa: tmfNeedsPng(type) dice se il MIME e' un'immagine fuori da PNG/JPEG/GIF/WebP;
+ * tmfImageToPng(file) la ridisegna su canvas e ritorna un File PNG (null se illeggibile, es. TIFF).
+ * Come si usa: await tmfImageToPng(file) prima del ritaglio e del caricamento.
+ * Dipende da: createImageBitmap e canvas del browser (non servono nei test: il caso "nessuna conversione" e' puro).
+ */
+// #107: tipi che il backend ammette gia': non vanno convertiti
+const TMF_PNG_PASSTHROUGH = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/webp'];
+
+// #107: true per un'immagine (image/*) non ammessa dal backend, es. image/bmp
+function tmfNeedsPng(type) {
+ return typeof type === 'string' && type.indexOf('image/') === 0 && TMF_PNG_PASSTHROUGH.indexOf(type) === -1;
+}
+
+// #107: converte in PNG con canvas; ritorna il file invariato se non serve, null se il browser non sa decodificarlo
+async function tmfImageToPng(file) {
+ if (!file || !tmfNeedsPng(file.type)) return file;
+ try {
+ const bitmap = await createImageBitmap(file);
+ const canvas = document.createElement('canvas');
+ canvas.width = bitmap.width;
+ canvas.height = bitmap.height;
+ canvas.getContext('2d').drawImage(bitmap, 0, 0);
+ if (bitmap.close) bitmap.close();
+ const blob = await new Promise(function (resolve) { canvas.toBlob(resolve, 'image/png'); });
+ if (!blob) return null;
+ const base = (file.name || 'immagine').replace(/\.[^.]+$/, '');
+ return new File([blob], base + '.png', { type: 'image/png' });
+ } catch (err) {
+ // #107: formato non decodificabile dal browser (es. TIFF)
+ return null;
+ }
+}
+
+// #107: export per il test node (nel browser module non esiste)
+if (typeof module !== 'undefined') module.exports = { tmfNeedsPng, tmfImageToPng };
diff --git a/src/frontend/flask_app/templates/maker/recipe_editor.html b/src/frontend/flask_app/templates/maker/recipe_editor.html
index 2d97091..5ea9128 100644
--- a/src/frontend/flask_app/templates/maker/recipe_editor.html
+++ b/src/frontend/flask_app/templates/maker/recipe_editor.html
@@ -504,6 +504,7 @@
{% block extra_js %}
+{# #107 #}
+{# #107 #}