📁 Add new image information directory

This commit is contained in:
2026-05-26 01:12:01 +08:00
parent c2e05244d1
commit 493efdba01
+109
View File
@@ -0,0 +1,109 @@
#!/usr/bin/env runts -- --runtime-bun
import {parseArgs} from "util";
const SUPPORTED_FORMATS = [".heic", ".jpeg", ".jpg", ".png", ".webp", ".gif", ".bmp", ".avif", ".tiff", ".tif"];
function printUsage() {
console.log(`Usage: bun run show-image.ts <image1> [image2] ...
Display detailed information about image files.
Arguments:
<image> ... Input image file(s)
Options:
--help Show this help message
Supported formats:
${SUPPORTED_FORMATS.join(", ")}
Examples:
bun run show-image.ts photo.jpg
bun run show-image.ts a.jpg b.heic c.png`);
}
function formatBytes(bytes: number): string {
if (bytes < 1024) return `${bytes} B`;
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
}
function getFormat(ext: string): string {
switch (ext) {
case ".jpg":
case ".jpeg":
return "JPEG";
case ".tif":
case ".tiff":
return "TIFF";
default:
return ext.slice(1).toUpperCase();
}
}
async function showImage(path: string) {
const file = Bun.file(path);
if (!(await file.exists())) {
console.error(`File not found: ${path}`);
return false;
}
const ext = "." + file.name?.split(".").pop()?.toLowerCase();
if (!SUPPORTED_FORMATS.includes(ext)) {
console.error(`Unsupported format: ${ext} (${path})`);
return false;
}
const image = file.image();
const meta = await image.metadata();
const size = file.size;
console.log(`File: ${path}`);
console.log(`Format: ${getFormat(ext)}`);
console.log(`Size: ${formatBytes(size)} (${size.toLocaleString()} bytes)`);
console.log(`Dimensions: ${meta.width} x ${meta.height}`);
console.log(`Aspect ratio: ${(meta.width / meta.height).toFixed(2)}`);
console.log(`Megapixels: ${((meta.width * meta.height) / 1_000_000).toFixed(2)} MP`);
console.log();
return true;
}
async function main() {
const args = Bun.argv.slice(2);
if (args.length === 0 || args.includes("--help")) {
printUsage();
process.exit(0);
}
const {positionals} = parseArgs({args, allowPositionals: true, strict: false});
if (positionals.length === 0) {
console.error("Error: No input files specified.\n");
printUsage();
process.exit(1);
}
let successCount = 0;
for (const path of positionals) {
const ok = await showImage(path);
if (ok) successCount++;
}
if (positionals.length > 1) {
console.log(`Total: ${successCount}/${positionals.length} file(s) processed.`);
}
if (successCount === 0) {
process.exit(1);
}
}
main().catch((err) => {
console.error(err);
});
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20260526T004141+08:00.MEQCIBjY8Rshew3TyWpojRAp
// /WewTldgEjhANbtyjw8Sn2VBAiARxfPLnmHlfkXZlVnN0lJoQmg1sqMmqouiHEjcxWQf3Q==