Heic support
This commit is contained in:
7
package-lock.json
generated
7
package-lock.json
generated
@@ -17,6 +17,7 @@
|
|||||||
"@types/google.accounts": "^0.0.17",
|
"@types/google.accounts": "^0.0.17",
|
||||||
"@types/uuid": "^10.0.0",
|
"@types/uuid": "^10.0.0",
|
||||||
"fontkit": "^2.0.4",
|
"fontkit": "^2.0.4",
|
||||||
|
"heic2any": "^0.0.4",
|
||||||
"idb": "^8.0.3",
|
"idb": "^8.0.3",
|
||||||
"pdf-lib": "^1.17.1",
|
"pdf-lib": "^1.17.1",
|
||||||
"uuid": "^11.1.0"
|
"uuid": "^11.1.0"
|
||||||
@@ -2255,6 +2256,12 @@
|
|||||||
"node": ">= 0.4"
|
"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": {
|
"node_modules/idb": {
|
||||||
"version": "8.0.3",
|
"version": "8.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/idb/-/idb-8.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/idb/-/idb-8.0.3.tgz",
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
"@types/google.accounts": "^0.0.17",
|
"@types/google.accounts": "^0.0.17",
|
||||||
"@types/uuid": "^10.0.0",
|
"@types/uuid": "^10.0.0",
|
||||||
"fontkit": "^2.0.4",
|
"fontkit": "^2.0.4",
|
||||||
|
"heic2any": "^0.0.4",
|
||||||
"idb": "^8.0.3",
|
"idb": "^8.0.3",
|
||||||
"pdf-lib": "^1.17.1",
|
"pdf-lib": "^1.17.1",
|
||||||
"uuid": "^11.1.0"
|
"uuid": "^11.1.0"
|
||||||
|
|||||||
@@ -116,18 +116,42 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let objectUrl: string;
|
let blob: Blob;
|
||||||
|
|
||||||
if (isGoogleDriveUrl(photo.url)) {
|
if (isGoogleDriveUrl(photo.url)) {
|
||||||
// Download from Google Drive
|
// Download from Google Drive
|
||||||
console.log(`Downloading from Google Drive: ${photo.name}`);
|
console.log(`Downloading from Google Drive: ${photo.name}`);
|
||||||
const blob = await downloadDriveImage(photo.url);
|
blob = await downloadDriveImage(photo.url);
|
||||||
objectUrl = createImageObjectUrl(blob);
|
|
||||||
} else {
|
} else {
|
||||||
// Use direct URL
|
// For direct URLs, convert to blob
|
||||||
objectUrl = photo.url;
|
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
|
// Test if image loads properly
|
||||||
await new Promise<void>((resolve, reject) => {
|
await new Promise<void>((resolve, reject) => {
|
||||||
const img = new Image();
|
const img = new Image();
|
||||||
@@ -144,36 +168,17 @@
|
|||||||
console.log(`Photo loaded successfully: ${photo.name}`);
|
console.log(`Photo loaded successfully: ${photo.name}`);
|
||||||
|
|
||||||
// Save to pictures store
|
// Save to pictures store
|
||||||
if (isGoogleDriveUrl(photo.url)) {
|
pictures.update(pics => ({
|
||||||
// For Google Drive images, save the blob
|
...pics,
|
||||||
const blob = await downloadDriveImage(photo.url);
|
[photo.url]: {
|
||||||
pictures.update(pics => ({
|
id: photo.url,
|
||||||
...pics,
|
blob: blob,
|
||||||
[photo.url]: {
|
url: objectUrl,
|
||||||
id: photo.url,
|
downloaded: true,
|
||||||
blob: blob,
|
faceDetected: false,
|
||||||
url: objectUrl,
|
faceCount: 0
|
||||||
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
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Automatically run face detection to generate crop
|
// Automatically run face detection to generate crop
|
||||||
await detectFaceForPhoto(index);
|
await detectFaceForPhoto(index);
|
||||||
@@ -410,7 +415,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<!-- Photo Grid -->
|
<!-- Photo Grid -->
|
||||||
<div class="bg-white overflow-hidden mb-6">
|
<div class="bg-white border border-gray-200 rounded-lg overflow-hidden mb-6">
|
||||||
{#if photos.length === 0 && !isProcessing}
|
{#if photos.length === 0 && !isProcessing}
|
||||||
<div class="text-center py-12">
|
<div class="text-center py-12">
|
||||||
<svg class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<svg class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
@@ -422,7 +427,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
|
<div class="p-6 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
|
||||||
{#each photos as photo, index}
|
{#each photos as photo, index}
|
||||||
<PhotoCard
|
<PhotoCard
|
||||||
{photo}
|
{photo}
|
||||||
|
|||||||
Reference in New Issue
Block a user