📂 Add new directory for image-scale-cli tool
This commit is contained in:
135
image-scale-cli/cli.ts
Normal file
135
image-scale-cli/cli.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
#!/usr/bin/env -S deno run --allow-read --allow-write
|
||||
|
||||
import { parseArgs } from "@std/cli/parse-args";
|
||||
import { scaleImage, type ScaleMode } from "./src/scaler.ts";
|
||||
import { scanDirectory } from "./src/scanner.ts";
|
||||
import { processBatch } from "./src/batch.ts";
|
||||
|
||||
const HELP = `
|
||||
scale-image-fixer - Scale images to fixed dimensions
|
||||
|
||||
Usage:
|
||||
deno run cli.ts <input> [options]
|
||||
deno run cli.ts <input...> [options] # Multiple files
|
||||
deno run cli.ts <directory> [options] # Directory mode
|
||||
|
||||
Arguments:
|
||||
input Input file path, multiple file paths, or directory path
|
||||
|
||||
Options:
|
||||
-w, --width <number> Output width (required)
|
||||
-h, --height <number> Output height (required)
|
||||
-m, --mode <mode> Scale mode: stretch, fit, cover (default: fit)
|
||||
-o, --output <path> Output path (file or directory)
|
||||
--help Show this help message
|
||||
|
||||
Scale Modes:
|
||||
stretch Resize to exact dimensions (may distort aspect ratio)
|
||||
fit Fit within dimensions while preserving aspect ratio
|
||||
cover Cover dimensions while preserving aspect ratio (crops excess)
|
||||
|
||||
Examples:
|
||||
deno run cli.ts input.png -w 800 -h 600
|
||||
deno run cli.ts input.jpg -w 400 -h 400 -m cover -o output.jpg
|
||||
deno run cli.ts ./images -w 200 -h 200 -o ./resized
|
||||
`;
|
||||
|
||||
interface Args {
|
||||
width?: number;
|
||||
height?: number;
|
||||
mode?: string;
|
||||
output?: string;
|
||||
help?: boolean;
|
||||
_: string[];
|
||||
}
|
||||
|
||||
function validateArgs(args: Args): { valid: boolean; error?: string } {
|
||||
if (args.help) {
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
if (args._.length === 0) {
|
||||
return { valid: false, error: "Input file, files, or directory is required" };
|
||||
}
|
||||
|
||||
if (!args.width || !args.height) {
|
||||
return { valid: false, error: "Width (-w) and height (-h) are required" };
|
||||
}
|
||||
|
||||
if (args.width <= 0 || args.height <= 0) {
|
||||
return { valid: false, error: "Width and height must be positive numbers" };
|
||||
}
|
||||
|
||||
const validModes = ["stretch", "fit", "cover"];
|
||||
if (args.mode && !validModes.includes(args.mode)) {
|
||||
return { valid: false, error: `Mode must be one of: ${validModes.join(", ")}` };
|
||||
}
|
||||
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const args = parseArgs(Deno.args, {
|
||||
string: ["width", "height", "mode", "output"],
|
||||
alias: {
|
||||
w: "width",
|
||||
h: "height",
|
||||
m: "mode",
|
||||
o: "output",
|
||||
},
|
||||
default: {
|
||||
mode: "fit",
|
||||
},
|
||||
}) as Args;
|
||||
|
||||
const validation = validateArgs(args);
|
||||
if (!validation.valid) {
|
||||
console.error(`Error: ${validation.error}`);
|
||||
console.log("\nUse --help for usage information");
|
||||
Deno.exit(1);
|
||||
}
|
||||
|
||||
if (args.help) {
|
||||
console.log(HELP);
|
||||
Deno.exit(0);
|
||||
}
|
||||
|
||||
const inputs = args._.map(String);
|
||||
const scaleMode: ScaleMode = (args.mode as ScaleMode) || "fit";
|
||||
const width = args.width!;
|
||||
const height = args.height!;
|
||||
const output = args.output;
|
||||
|
||||
try {
|
||||
// Check if inputs are files or directory
|
||||
const firstInput = await Deno.stat(inputs[0]);
|
||||
|
||||
if (firstInput.isDirectory) {
|
||||
// Directory mode: scan and batch process
|
||||
const images = await scanDirectory(inputs[0]);
|
||||
if (images.length === 0) {
|
||||
console.log("No supported images found in directory");
|
||||
Deno.exit(0);
|
||||
}
|
||||
await processBatch(images, { width, height, mode: scaleMode, outputDir: output });
|
||||
} else if (inputs.length > 1) {
|
||||
// Multiple files mode
|
||||
await processBatch(inputs, { width, height, mode: scaleMode, outputDir: output });
|
||||
} else {
|
||||
// Single file mode
|
||||
const result = await scaleImage(inputs[0], { width, height, mode: scaleMode, output });
|
||||
console.log(`Scaled: ${result.input} → ${result.output}`);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Deno.errors.NotFound) {
|
||||
console.error(`Error: File or directory not found: ${inputs[0]}`);
|
||||
} else if (error instanceof Error) {
|
||||
console.error(`Error: ${error.message}`);
|
||||
} else {
|
||||
console.error("An unexpected error occurred");
|
||||
}
|
||||
Deno.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
await main();
|
||||
Reference in New Issue
Block a user