Files
dashlibstorage/src/util/processAvifImage.js
2026-08-01 03:37:45 +02:00

71 lines
1.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import sharp from 'sharp';
import { rgbaToThumbHash } from 'thumbhash';
const FULL_MAX = 1000;
const THUMB_MAX = 200;
export default async function processAvifImage(inputBuffer) {
const input = Buffer.isBuffer(inputBuffer)
? inputBuffer
: Buffer.from(inputBuffer);
const meta = await sharp(input).metadata();
const w = meta.width ?? 0;
const h = meta.height ?? 0;
const isAvif =
meta.format === 'avif' ||
(meta.format === 'heif' && meta.compression === 'av1');
const useOriginalFull =
isAvif && w > 0 && h > 0 && w <= FULL_MAX && h <= FULL_MAX;
if (!useOriginalFull) {
console.log(
`processAvifImage: converting full image (format=${meta.format ?? 'unknown'}, ${w}×${h}, avif=${isAvif})`,
);
}
const thumbPipeline = sharp(input)
.resize(THUMB_MAX, THUMB_MAX, { fit: 'inside', withoutEnlargement: true });
const [full, thumb, thumbRgba] = await Promise.all([
useOriginalFull
? Promise.resolve({
info: { width: w, height: h },
data: input,
})
: sharp(input)
.resize(FULL_MAX, FULL_MAX, { fit: 'inside', withoutEnlargement: true })
.avif({ effort: 4 })
.toBuffer({ resolveWithObject: true }),
thumbPipeline.clone().avif({ effort: 4 }).toBuffer({ resolveWithObject: true }),
thumbPipeline
.clone()
.resize(100, 100, { fit: 'inside', withoutEnlargement: true })
.ensureAlpha()
.raw()
.toBuffer({ resolveWithObject: true }),
]);
const thumbHashBytes = rgbaToThumbHash(
thumbRgba.info.width,
thumbRgba.info.height,
thumbRgba.data,
);
return {
full: {
w: full.info.width,
h: full.info.height,
size: full.data.length,
buffer: full.data,
},
thumb: {
w: thumb.info.width,
h: thumb.info.height,
size: thumb.data.length,
buffer: thumb.data,
hash: Buffer.from(thumbHashBytes).toString('base64'),
},
};
}