56 lines
1.3 KiB
TypeScript
56 lines
1.3 KiB
TypeScript
import type sharp from "sharp";
|
|
import { getFormat } from "./loader.ts";
|
|
|
|
export interface SaveOptions {
|
|
quality?: number;
|
|
compressionLevel?: number;
|
|
}
|
|
|
|
/**
|
|
* Save a sharp instance to a file with format-specific options
|
|
*/
|
|
export async function saveImage(
|
|
image: sharp.Sharp,
|
|
outputPath: string,
|
|
options: SaveOptions = {}
|
|
): Promise<string> {
|
|
const { quality = 85, compressionLevel = 6 } = options;
|
|
const format = getFormat(outputPath);
|
|
|
|
let processed: sharp.Sharp;
|
|
|
|
switch (format) {
|
|
case "jpeg":
|
|
processed = image.jpeg({ quality });
|
|
break;
|
|
case "png":
|
|
processed = image.png({ compressionLevel });
|
|
break;
|
|
case "webp":
|
|
processed = image.webp({ quality });
|
|
break;
|
|
case "gif":
|
|
processed = image.gif();
|
|
break;
|
|
default:
|
|
throw new Error(`Unsupported output format: ${format}`);
|
|
}
|
|
|
|
await processed.toFile(outputPath);
|
|
return outputPath;
|
|
}
|
|
|
|
/**
|
|
* Determine output path based on input and options
|
|
*/
|
|
export function determineOutputPath(
|
|
inputPath: string,
|
|
explicitOutput?: string
|
|
): string {
|
|
if (explicitOutput) {
|
|
return explicitOutput;
|
|
}
|
|
// Default: add -scaled suffix before extension
|
|
return inputPath.replace(/\.[^.]+$/, `-scaled${inputPath.match(/\.[^.]+$/)?.[0] || ""}`);
|
|
}
|