71 lines
1.9 KiB
JavaScript
71 lines
1.9 KiB
JavaScript
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'),
|
||
},
|
||
};
|
||
}
|