브라우저가 heic 디코딩을 지원하는 경우 heic2any를 사용하지 않도록 개선 및 브라우저가 webp 인코딩을 지원하지 않는 경우 썸네일을 생성하지 않도록 수정

This commit is contained in:
static
2025-07-12 19:44:16 +09:00
parent 393bba45db
commit 301216915e
2 changed files with 38 additions and 21 deletions

View File

@@ -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);

View File

@@ -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}
<img src={fileBlobUrl} alt={$info.name} />
<img src={fileBlobUrl} alt={$info.name} onerror={convertHeicToJpeg} />
{:else}
{@render viewerLoading("이미지를 불러오고 있어요.")}
{/if}