sssg/src/plugins/image-optimization.ts

68 lines
1.7 KiB
TypeScript

import { Plugin } from "..";
import sharp from "sharp";
export default class ImageOptimization extends Plugin {
build: undefined;
name = "image-optimization";
rewriteTriggers = ["png", "gif", "jpg", "jpeg", "webp", "avif"];
renameTo = "keep";
isBinary = true;
longLasting = false;
logging = true;
constructor(logging = true) {
super();
this.logging = logging;
}
async rewriteFile(file: Buffer, filePath: string) {
const nonOptimized = file;
const type = filePath.split(".").at(-1);
let data: Buffer = file;
if (type == "webp") {
data = await sharp(file).webp({ lossless: true }).toBuffer();
}
if (type == "avif") {
data = await sharp(file).avif({ lossless: true }).toBuffer();
}
if (type == "jpg" || type == "jpeg") {
data = await sharp(file).jpeg({ quality: 100 }).toBuffer();
}
if (type == "png") {
data = await sharp(file).png({ quality: 100 }).toBuffer();
}
if (type == "gif") {
const gif = sharp(file, { animated: true });
const pageCount = (await gif.metadata()).pages;
if (pageCount == 1) {
data = await sharp(file, { animated: false })
.gif({ colors: 16 })
.toBuffer();
} else {
data = await sharp(file, { animated: true })
.gif({ colors: 16 })
.toBuffer();
}
}
if (nonOptimized.byteLength < data.byteLength) {
if (this.logging) {
console.log(
"❌ " +
filePath +
"(" +
nonOptimized.byteLength +
"B) optimized was " +
data.byteLength +
"B. It has been skipped."
);
}
data = nonOptimized;
}
return data;
}
}