diff --git a/package-lock.json b/package-lock.json index f8fdbbb..789df5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "@types/google.accounts": "^0.0.17", "@types/uuid": "^10.0.0", "fontkit": "^2.0.4", + "heic2any": "^0.0.4", "idb": "^8.0.3", "pdf-lib": "^1.17.1", "uuid": "^11.1.0" @@ -2255,6 +2256,12 @@ "node": ">= 0.4" } }, + "node_modules/heic2any": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/heic2any/-/heic2any-0.0.4.tgz", + "integrity": "sha512-3lLnZiDELfabVH87htnRolZ2iehX9zwpRyGNz22GKXIu0fznlblf0/ftppXKNqS26dqFSeqfIBhAmAj/uSp0cA==", + "license": "MIT" + }, "node_modules/idb": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/idb/-/idb-8.0.3.tgz", diff --git a/package.json b/package.json index 12d3599..016b904 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "@types/google.accounts": "^0.0.17", "@types/uuid": "^10.0.0", "fontkit": "^2.0.4", + "heic2any": "^0.0.4", "idb": "^8.0.3", "pdf-lib": "^1.17.1", "uuid": "^11.1.0" diff --git a/src/lib/components/wizard/StepGallery.svelte b/src/lib/components/wizard/StepGallery.svelte index 0dc8506..014e819 100644 --- a/src/lib/components/wizard/StepGallery.svelte +++ b/src/lib/components/wizard/StepGallery.svelte @@ -116,18 +116,42 @@ } try { - let objectUrl: string; + let blob: Blob; if (isGoogleDriveUrl(photo.url)) { // Download from Google Drive console.log(`Downloading from Google Drive: ${photo.name}`); - const blob = await downloadDriveImage(photo.url); - objectUrl = createImageObjectUrl(blob); + blob = await downloadDriveImage(photo.url); } else { - // Use direct URL - objectUrl = photo.url; + // For direct URLs, convert to blob + const response = await fetch(photo.url); + blob = await response.blob(); } + // Check for HEIC/HEIF format and convert if necessary + if ( + blob.type === 'image/heic' || + blob.type === 'image/heif' || + photo.url.toLowerCase().endsWith('.heic') + ) { + console.log(`Converting HEIC image for ${photo.name}...`); + try { + const { default: heic2any } = await import('heic2any'); + const conversionResult = await heic2any({ + blob, + toType: 'image/jpeg', + quality: 0.9 + }); + blob = Array.isArray(conversionResult) ? conversionResult[0] : conversionResult; + console.log(`Successfully converted HEIC for ${photo.name}`); + } catch (e) { + console.error(`Failed to convert HEIC image for ${photo.name}:`, e); + throw new Error('HEIC conversion failed'); + } + } + + const objectUrl = createImageObjectUrl(blob); + // Test if image loads properly await new Promise((resolve, reject) => { const img = new Image(); @@ -144,36 +168,17 @@ console.log(`Photo loaded successfully: ${photo.name}`); // Save to pictures store - if (isGoogleDriveUrl(photo.url)) { - // For Google Drive images, save the blob - const blob = await downloadDriveImage(photo.url); - pictures.update(pics => ({ - ...pics, - [photo.url]: { - id: photo.url, - blob: blob, - url: objectUrl, - downloaded: true, - faceDetected: false, - faceCount: 0 - } - })); - } else { - // For direct URLs, convert to blob - const response = await fetch(photo.url); - const blob = await response.blob(); - pictures.update(pics => ({ - ...pics, - [photo.url]: { - id: photo.url, - blob: blob, - url: objectUrl, - downloaded: true, - faceDetected: false, - faceCount: 0 - } - })); - } + pictures.update(pics => ({ + ...pics, + [photo.url]: { + id: photo.url, + blob: blob, + url: objectUrl, + downloaded: true, + faceDetected: false, + faceCount: 0 + } + })); // Automatically run face detection to generate crop await detectFaceForPhoto(index); @@ -410,7 +415,7 @@ {/if} -
+
{#if photos.length === 0 && !isProcessing}
@@ -422,7 +427,7 @@

{:else} -
+
{#each photos as photo, index}