|
|
@ -16,7 +16,63 @@ settings.subscribe(b => { |
|
|
|
csettings = b; |
|
|
|
}); |
|
|
|
|
|
|
|
const generateUglyThumbnail = async (f: File): Promise<Buffer> => { |
|
|
|
const can = document.createElement("canvas"); |
|
|
|
|
|
|
|
const [sw, sh] = [125, 125]; |
|
|
|
const url = URL.createObjectURL(f); |
|
|
|
|
|
|
|
let source: CanvasImageSource; |
|
|
|
let iw: number, ih: number; |
|
|
|
|
|
|
|
if (f.type.startsWith("image")) { |
|
|
|
const imgElem = document.createElement('img'); |
|
|
|
imgElem.src = url; |
|
|
|
await new Promise(_ => imgElem.onload = _); |
|
|
|
[iw, ih] = [imgElem.naturalWidth, imgElem.naturalHeight]; |
|
|
|
source = imgElem; |
|
|
|
} else if (f.type.startsWith("video")) { |
|
|
|
const vidElem = document.createElement('video'); |
|
|
|
vidElem.src = url; |
|
|
|
await new Promise(_ => vidElem.onloadedmetadata = _); |
|
|
|
vidElem.currentTime = 0; |
|
|
|
await new Promise(_ => vidElem.onloadeddata = _); |
|
|
|
await new Promise(requestAnimationFrame); |
|
|
|
await new Promise(requestAnimationFrame); |
|
|
|
await new Promise(requestAnimationFrame); |
|
|
|
[iw, ih] = [vidElem.videoWidth, vidElem.videoHeight]; |
|
|
|
source = vidElem; |
|
|
|
} else |
|
|
|
return Buffer.alloc(0); |
|
|
|
|
|
|
|
const scale = Math.min(1, sw / iw, sh / ih); |
|
|
|
const dims = [~~(iw * scale), ~~(ih * scale)] as [number, number]; |
|
|
|
|
|
|
|
can.width = dims[0]; |
|
|
|
can.height = dims[1]; |
|
|
|
|
|
|
|
const ctx = can.getContext("2d"); |
|
|
|
|
|
|
|
if (!ctx) |
|
|
|
return Buffer.alloc(0); |
|
|
|
|
|
|
|
ctx.drawImage(source, 0, 0, dims[0], dims[1]); |
|
|
|
|
|
|
|
const blob = await new Promise<Blob | null>(_ => can.toBlob(_)); |
|
|
|
if (!blob) |
|
|
|
return Buffer.alloc(0); |
|
|
|
return Buffer.from(await blob.arrayBuffer()); |
|
|
|
}; |
|
|
|
|
|
|
|
const generateThumbnail = async (f: File): Promise<Buffer> => { |
|
|
|
try { |
|
|
|
return await generateProperThumbnail(f); |
|
|
|
} catch { |
|
|
|
return await generateUglyThumbnail(f); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
const generateProperThumbnail = async (f: File): Promise<Buffer> => { |
|
|
|
const can = document.createElement("canvas"); |
|
|
|
|
|
|
|
const [sw, sh] = [125, 125]; |
|
|
|