diff --git a/src/lib/modules/thumbnail.ts b/src/lib/modules/thumbnail.ts
index 9c009bd..2d5cd55 100644
--- a/src/lib/modules/thumbnail.ts
+++ b/src/lib/modules/thumbnail.ts
@@ -32,7 +32,7 @@ const capture = (
drawer(context, scaledWidth, scaledHeight);
canvas.toBlob((blob) => {
- if (blob) {
+ if (blob && blob.type === "image/webp") {
resolve(blob);
} else {
reject(new Error("Failed to generate thumbnail"));
@@ -83,18 +83,26 @@ const generateVideoThumbnail = (videoUrl: string, time = 0) => {
export const generateThumbnail = async (fileBuffer: ArrayBuffer, fileType: string) => {
let url;
try {
- if (fileType === "image/heic") {
- const { default: heic2any } = await import("heic2any");
- url = URL.createObjectURL(
- (await heic2any({
- blob: new Blob([fileBuffer], { type: fileType }),
- toType: "image/png",
- })) as Blob,
- );
- return await generateImageThumbnail(url);
- } else if (fileType.startsWith("image/")) {
- url = URL.createObjectURL(new Blob([fileBuffer], { type: fileType }));
- return await generateImageThumbnail(url);
+ if (fileType.startsWith("image/")) {
+ const fileBlob = new Blob([fileBuffer], { type: fileType });
+ url = URL.createObjectURL(fileBlob);
+
+ try {
+ return await generateImageThumbnail(url);
+ } catch {
+ URL.revokeObjectURL(url);
+ url = undefined;
+
+ if (fileType === "image/heic") {
+ const { default: heic2any } = await import("heic2any");
+ url = URL.createObjectURL(
+ (await heic2any({ blob: fileBlob, toType: "image/png" })) as Blob,
+ );
+ return await generateImageThumbnail(url);
+ } else {
+ return null;
+ }
+ }
} else if (fileType.startsWith("video/")) {
url = URL.createObjectURL(new Blob([fileBuffer], { type: fileType }));
return await generateVideoThumbnail(url);
diff --git a/src/routes/(fullscreen)/file/[id]/+page.svelte b/src/routes/(fullscreen)/file/[id]/+page.svelte
index 61465bd..4047e7c 100644
--- a/src/routes/(fullscreen)/file/[id]/+page.svelte
+++ b/src/routes/(fullscreen)/file/[id]/+page.svelte
@@ -43,22 +43,31 @@
let isDownloadRequested = $state(false);
let viewerType: "image" | "video" | undefined = $state();
let fileBlobUrl: string | undefined = $state();
+ let heicBlob: Blob | undefined = $state();
let videoElement: HTMLVideoElement | undefined = $state();
const updateViewer = async (buffer: ArrayBuffer, contentType: string) => {
const fileBlob = new Blob([buffer], { type: contentType });
- if (contentType === "image/heic") {
- const { default: heic2any } = await import("heic2any");
- fileBlobUrl = URL.createObjectURL(
- (await heic2any({ blob: fileBlob, toType: "image/jpeg" })) as Blob,
- );
- } else if (viewerType) {
+ if (viewerType) {
fileBlobUrl = URL.createObjectURL(fileBlob);
+ heicBlob = contentType === "image/heic" ? fileBlob : undefined;
}
-
return fileBlob;
};
+ const convertHeicToJpeg = async () => {
+ if (!heicBlob) return;
+
+ URL.revokeObjectURL(fileBlobUrl!);
+ fileBlobUrl = undefined;
+
+ const { default: heic2any } = await import("heic2any");
+ fileBlobUrl = URL.createObjectURL(
+ (await heic2any({ blob: heicBlob, toType: "image/jpeg" })) as Blob,
+ );
+ heicBlob = undefined;
+ };
+
const updateThumbnail = async (dataKey: CryptoKey, dataKeyVersion: Date) => {
const thumbnail = await captureVideoThumbnail(videoElement!);
await requestThumbnailUpload(data.id, thumbnail, dataKey, dataKeyVersion);
@@ -136,7 +145,7 @@
{#if viewerType === "image"}
{#if fileBlobUrl}
-
+
{:else}
{@render viewerLoading("이미지를 불러오고 있어요.")}
{/if}