feat: trying to make image generation faster
This commit is contained in:
@@ -5,55 +5,26 @@ import { readFile } from "node:fs/promises";
|
||||
import sharp from "sharp";
|
||||
|
||||
export async function generateThumbHash(
|
||||
image: ImageMetadata & { fsPath?: string },
|
||||
) {
|
||||
const scaleFactor = 100 / Math.max(image.width, image.height);
|
||||
buffer: ArrayBuffer,
|
||||
): Promise<string | undefined> {
|
||||
if (!buffer) return;
|
||||
|
||||
let smallWidth = Math.floor(image.width * scaleFactor);
|
||||
let smallHeight = Math.floor(image.height * scaleFactor);
|
||||
const sp = sharp(buffer);
|
||||
|
||||
try {
|
||||
const imagePath = (image as ImageMetadata & { fsPath: string }).fsPath ??
|
||||
image.src;
|
||||
const meta = await sp.metadata();
|
||||
const scaleFactor = 100 / Math.max(meta.width, meta.height);
|
||||
const smallWidth = Math.floor(meta.width * scaleFactor);
|
||||
const smallHeight = Math.floor(meta.height * scaleFactor);
|
||||
|
||||
if (!imagePath) return;
|
||||
const smallImg = await sp
|
||||
.resize(smallWidth, smallHeight)
|
||||
.withMetadata()
|
||||
.raw()
|
||||
.ensureAlpha()
|
||||
.toBuffer();
|
||||
|
||||
if (imagePath.endsWith(".svg")) return;
|
||||
|
||||
let sp: ReturnType<typeof sharp>;
|
||||
if (imagePath.startsWith("https://") || imagePath.startsWith("http://")) {
|
||||
const res = await fetch(imagePath);
|
||||
if (!res.ok) {
|
||||
return;
|
||||
}
|
||||
const buffer = await res.arrayBuffer();
|
||||
sp = sharp(buffer);
|
||||
} else {
|
||||
sp = sharp(imagePath);
|
||||
}
|
||||
|
||||
if (!smallWidth || !smallHeight) {
|
||||
const meta = await sp.metadata();
|
||||
const scaleFactor = 100 / Math.max(meta.width, meta.height);
|
||||
smallWidth = Math.floor(meta.width * scaleFactor);
|
||||
smallHeight = Math.floor(meta.height * scaleFactor);
|
||||
}
|
||||
|
||||
const smallImg = await sp
|
||||
.resize(smallWidth, smallHeight)
|
||||
.withMetadata()
|
||||
.raw()
|
||||
.ensureAlpha()
|
||||
.toBuffer();
|
||||
|
||||
const buffer = rgbaToThumbHash(smallWidth, smallHeight, smallImg);
|
||||
return Buffer.from(buffer).toString("base64");
|
||||
} catch (_error) {
|
||||
console.log(
|
||||
`Could not generate thumbhash for ${image.fsPath ?? image.src}`,
|
||||
);
|
||||
return "";
|
||||
}
|
||||
const hashBuffer = rgbaToThumbHash(smallWidth, smallHeight, smallImg);
|
||||
return Buffer.from(hashBuffer).toString("base64");
|
||||
}
|
||||
|
||||
const allowedExif = [
|
||||
@@ -72,7 +43,9 @@ const allowedExif = [
|
||||
"Model",
|
||||
];
|
||||
|
||||
export async function getExifData(image: ImageMetadata) {
|
||||
export async function getImageBuffer(
|
||||
image: ImageMetadata,
|
||||
): Promise<ArrayBuffer> {
|
||||
if (image.format === "svg") return undefined; // SVGs don't have EXIF data
|
||||
const imagePath = (image as ImageMetadata & { fsPath: string }).fsPath ??
|
||||
image.src;
|
||||
@@ -80,31 +53,31 @@ export async function getExifData(image: ImageMetadata) {
|
||||
if (!imagePath) return undefined;
|
||||
|
||||
try {
|
||||
let buffer: ArrayBufferLike;
|
||||
if (imagePath.startsWith("https://") || imagePath.startsWith("http://")) {
|
||||
const res = await fetch(imagePath);
|
||||
buffer = await res.arrayBuffer();
|
||||
const res = await fetch(imagePath, { signal: AbortSignal.timeout(5000) });
|
||||
return await res.arrayBuffer();
|
||||
} else {
|
||||
const b = await readFile(imagePath);
|
||||
buffer = b.buffer;
|
||||
return b.buffer as ArrayBuffer;
|
||||
}
|
||||
|
||||
const tags = await ExifReader.load(buffer, { async: true });
|
||||
|
||||
if (!buffer) return undefined;
|
||||
|
||||
const out: Record<string, any> = {};
|
||||
let hasExif = false;
|
||||
|
||||
for (const key of allowedExif) {
|
||||
if (!tags[key]) continue;
|
||||
hasExif = true;
|
||||
out[key] = tags[key]?.description;
|
||||
}
|
||||
|
||||
return hasExif ? out : undefined;
|
||||
} catch (error) {
|
||||
console.log(`Error reading EXIF data from ${JSON.stringify(image)}`, error);
|
||||
} catch (err) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getExifData(buffer: ArrayBuffer) {
|
||||
if (!buffer) return undefined;
|
||||
|
||||
const tags = await ExifReader.load(buffer, { async: true });
|
||||
|
||||
const out: Record<string, unknown> = {};
|
||||
let hasExif = false;
|
||||
|
||||
for (const key of allowedExif) {
|
||||
if (!tags[key]) continue;
|
||||
hasExif = true;
|
||||
out[key] = tags[key]?.description;
|
||||
}
|
||||
|
||||
return hasExif ? out : undefined;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user