add image scale [not tested]
This commit is contained in:
117
image-scale/main.ts
Normal file
117
image-scale/main.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import sharp from "sharp";
|
||||
import { parseArgs } from "@std/cli/parse-args";
|
||||
import { basename, extname, join } from "@std/path";
|
||||
|
||||
/**
|
||||
* Resize an image so that its smallest dimension equals the specified minimum pixels.
|
||||
* Output format is always JPG.
|
||||
*
|
||||
* @param inputPath - Path to the input image (PNG or JPG)
|
||||
* @param outputPath - Path to the output JPG image
|
||||
* @param minPixels - The minimum dimension (width or height) in pixels
|
||||
*/
|
||||
export async function scaleImage(
|
||||
inputPath: string,
|
||||
outputPath: string,
|
||||
minPixels: number,
|
||||
): Promise<void> {
|
||||
if (minPixels <= 0) {
|
||||
throw new Error("minPixels must be a positive number");
|
||||
}
|
||||
|
||||
const metadata = await sharp(inputPath).metadata();
|
||||
const originalWidth = metadata.width;
|
||||
const originalHeight = metadata.height;
|
||||
|
||||
if (!originalWidth || !originalHeight) {
|
||||
throw new Error("Could not determine image dimensions");
|
||||
}
|
||||
|
||||
// Calculate the scale factor based on the smaller dimension
|
||||
const minDimension = Math.min(originalWidth, originalHeight);
|
||||
const scaleFactor = minPixels / minDimension;
|
||||
|
||||
const newWidth = Math.round(originalWidth * scaleFactor);
|
||||
const newHeight = Math.round(originalHeight * scaleFactor);
|
||||
|
||||
await sharp(inputPath)
|
||||
.resize(newWidth, newHeight)
|
||||
.jpeg({ quality: 90 })
|
||||
.toFile(outputPath);
|
||||
|
||||
console.log(
|
||||
`Resized: ${originalWidth}x${originalHeight} -> ${newWidth}x${newHeight} (min dimension: ${minPixels}px)`,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate output path for the scaled image.
|
||||
* Changes the extension to .jpg
|
||||
*/
|
||||
export function getOutputPath(inputPath: string, outputDir?: string): string {
|
||||
const base = basename(inputPath, extname(inputPath));
|
||||
const dir = outputDir || join(inputPath, "..");
|
||||
return join(dir, `${base}.jpg`);
|
||||
}
|
||||
|
||||
function printUsage() {
|
||||
console.log(`
|
||||
Usage: deno run --allow-read --allow-write main.ts <input-image> [options]
|
||||
|
||||
Arguments:
|
||||
input-image Path to the input image (PNG or JPG)
|
||||
|
||||
Options:
|
||||
--min-pixels, -m Minimum dimension in pixels (default: 1200)
|
||||
--output, -o Output directory or file path
|
||||
--help, -h Show this help message
|
||||
|
||||
Examples:
|
||||
deno run --allow-read --allow-write main.ts input.png -m 1200
|
||||
deno run --allow-read --allow-write main.ts input.jpg -m 800 -o ./output
|
||||
deno run --allow-read --allow-write main.ts input.png -m 1920 -o ./resized.jpg
|
||||
`);
|
||||
}
|
||||
|
||||
if (import.meta.main) {
|
||||
const flags = parseArgs(Deno.args, {
|
||||
string: ["output", "o", "min-pixels", "m"],
|
||||
boolean: ["help", "h"],
|
||||
alias: {
|
||||
"min-pixels": "m",
|
||||
output: "o",
|
||||
help: "h",
|
||||
},
|
||||
default: {
|
||||
"min-pixels": "1200",
|
||||
},
|
||||
});
|
||||
|
||||
if (flags.help) {
|
||||
printUsage();
|
||||
Deno.exit(0);
|
||||
}
|
||||
|
||||
const inputPath = flags._[0] as string | undefined;
|
||||
|
||||
if (!inputPath) {
|
||||
console.error("Error: Input image path is required");
|
||||
printUsage();
|
||||
Deno.exit(1);
|
||||
}
|
||||
|
||||
const minPixels = parseInt(flags["min-pixels"] as string, 10);
|
||||
const outputPath = flags.output
|
||||
? flags.output.endsWith(".jpg") || flags.output.endsWith(".jpeg")
|
||||
? flags.output as string
|
||||
: getOutputPath(inputPath, flags.output as string)
|
||||
: getOutputPath(inputPath);
|
||||
|
||||
try {
|
||||
await scaleImage(inputPath, outputPath, minPixels);
|
||||
console.log(`Output saved to: ${outputPath}`);
|
||||
} catch (error) {
|
||||
console.error("Error:", error instanceof Error ? error.message : error);
|
||||
Deno.exit(1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user