update image scale
This commit is contained in:
71
image-scale/main.ts
Normal file → Executable file
71
image-scale/main.ts
Normal file → Executable file
@@ -1,6 +1,7 @@
|
|||||||
|
#!/usr/bin/env -S deno run -A
|
||||||
|
|
||||||
import sharp from "sharp";
|
import sharp from "sharp";
|
||||||
import { parseArgs } from "@std/cli/parse-args";
|
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.
|
* Resize an image so that its smallest dimension equals the specified minimum pixels.
|
||||||
@@ -14,6 +15,7 @@ export async function scaleImage(
|
|||||||
inputPath: string,
|
inputPath: string,
|
||||||
outputPath: string,
|
outputPath: string,
|
||||||
minPixels: number,
|
minPixels: number,
|
||||||
|
quality?: number,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (minPixels <= 0) {
|
if (minPixels <= 0) {
|
||||||
throw new Error("minPixels must be a positive number");
|
throw new Error("minPixels must be a positive number");
|
||||||
@@ -27,6 +29,13 @@ export async function scaleImage(
|
|||||||
throw new Error("Could not determine image dimensions");
|
throw new Error("Could not determine image dimensions");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (originalWidth < minPixels || originalHeight < minPixels) {
|
||||||
|
// original width or height is less than min pixels, should not scale image
|
||||||
|
throw new Error(
|
||||||
|
`Image width ${originalWidth} and/or height ${originalHeight} less then ${minPixels}, cannot scale image`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate the scale factor based on the smaller dimension
|
// Calculate the scale factor based on the smaller dimension
|
||||||
const minDimension = Math.min(originalWidth, originalHeight);
|
const minDimension = Math.min(originalWidth, originalHeight);
|
||||||
const scaleFactor = minPixels / minDimension;
|
const scaleFactor = minPixels / minDimension;
|
||||||
@@ -36,7 +45,7 @@ export async function scaleImage(
|
|||||||
|
|
||||||
await sharp(inputPath)
|
await sharp(inputPath)
|
||||||
.resize(newWidth, newHeight)
|
.resize(newWidth, newHeight)
|
||||||
.jpeg({ quality: 90 })
|
.jpeg({ quality: quality ?? 90 })
|
||||||
.toFile(outputPath);
|
.toFile(outputPath);
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
@@ -48,10 +57,20 @@ export async function scaleImage(
|
|||||||
* Generate output path for the scaled image.
|
* Generate output path for the scaled image.
|
||||||
* Changes the extension to .jpg
|
* Changes the extension to .jpg
|
||||||
*/
|
*/
|
||||||
export function getOutputPath(inputPath: string, outputDir?: string): string {
|
export function getOutputPath(
|
||||||
const base = basename(inputPath, extname(inputPath));
|
inputPath: string,
|
||||||
const dir = outputDir || join(inputPath, "..");
|
unsafeReplaceFile: boolean,
|
||||||
return join(dir, `${base}.jpg`);
|
): string {
|
||||||
|
if (unsafeReplaceFile) {
|
||||||
|
const lowerInputPath = inputPath.toLowerCase();
|
||||||
|
if (lowerInputPath.endsWith(".jpg") || lowerInputPath.endsWith(".jpeg")) {
|
||||||
|
return inputPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const lastDot = inputPath.lastIndexOf(".");
|
||||||
|
return lastDot !== -1
|
||||||
|
? `${inputPath.slice(0, lastDot)}${unsafeReplaceFile ? "" : "_scaled"}.jpg`
|
||||||
|
: `${inputPath}${unsafeReplaceFile ? "" : "_scaled"}.jpg`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function printUsage() {
|
function printUsage() {
|
||||||
@@ -75,15 +94,17 @@ Examples:
|
|||||||
|
|
||||||
if (import.meta.main) {
|
if (import.meta.main) {
|
||||||
const flags = parseArgs(Deno.args, {
|
const flags = parseArgs(Deno.args, {
|
||||||
string: ["output", "o", "min-pixels", "m"],
|
string: ["output", "o", "min-pixels", "m", "quality", "q"],
|
||||||
boolean: ["help", "h"],
|
boolean: ["help", "h", "unsafe-replace-file"],
|
||||||
alias: {
|
alias: {
|
||||||
"min-pixels": "m",
|
"min-pixels": "m",
|
||||||
output: "o",
|
output: "o",
|
||||||
help: "h",
|
help: "h",
|
||||||
|
quality: "q",
|
||||||
},
|
},
|
||||||
default: {
|
default: {
|
||||||
"min-pixels": "1200",
|
"min-pixels": "1200",
|
||||||
|
"quality": "90",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -92,26 +113,30 @@ if (import.meta.main) {
|
|||||||
Deno.exit(0);
|
Deno.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const inputPath = flags._[0] as string | undefined;
|
const imagePaths = flags._;
|
||||||
|
|
||||||
if (!inputPath) {
|
if (imagePaths.length == 0) {
|
||||||
console.error("Error: Input image path is required");
|
console.error("No image paths found.");
|
||||||
printUsage();
|
printUsage();
|
||||||
Deno.exit(1);
|
Deno.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const minPixels = parseInt(flags["min-pixels"] as string, 10);
|
const minPixels = parseInt(flags["min-pixels"] as string, 10);
|
||||||
const outputPath = flags.output
|
const quality = parseInt(flags["quality"] as string, 10);
|
||||||
? flags.output.endsWith(".jpg") || flags.output.endsWith(".jpeg")
|
const unsafeReplaceFile = flags["unsafe-replace-file"];
|
||||||
? flags.output as string
|
console.log(
|
||||||
: getOutputPath(inputPath, flags.output as string)
|
`Image scale config, min-pixels: ${minPixels}, quality: ${quality}, unsafe-replace-file: ${unsafeReplaceFile}`,
|
||||||
: getOutputPath(inputPath);
|
);
|
||||||
|
|
||||||
try {
|
for (const imagePath of imagePaths) {
|
||||||
await scaleImage(inputPath, outputPath, minPixels);
|
const imagePathStr = imagePath as string;
|
||||||
console.log(`Output saved to: ${outputPath}`);
|
const outputPath = getOutputPath(imagePathStr, unsafeReplaceFile);
|
||||||
} catch (error) {
|
|
||||||
console.error("Error:", error instanceof Error ? error.message : error);
|
try {
|
||||||
Deno.exit(1);
|
await scaleImage(imagePathStr, outputPath, minPixels, quality);
|
||||||
|
console.log(`Output saved to: ${outputPath}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error:", error instanceof Error ? error.message : error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user