add image scale [not tested]
This commit is contained in:
13
image-scale/deno.json
Normal file
13
image-scale/deno.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"nodeModulesDir": "auto",
|
||||
"tasks": {
|
||||
"dev": "deno run --watch main.ts",
|
||||
"start": "deno run --allow-read --allow-write --allow-env --allow-ffi main.ts"
|
||||
},
|
||||
"imports": {
|
||||
"@std/assert": "jsr:@std/assert@1",
|
||||
"@std/cli": "jsr:@std/cli@1",
|
||||
"@std/path": "jsr:@std/path@1",
|
||||
"sharp": "npm:sharp@^0.33"
|
||||
}
|
||||
}
|
||||
240
image-scale/deno.lock
generated
Normal file
240
image-scale/deno.lock
generated
Normal file
@@ -0,0 +1,240 @@
|
||||
{
|
||||
"version": "5",
|
||||
"specifiers": {
|
||||
"jsr:@std/assert@1": "1.0.13",
|
||||
"jsr:@std/cli@1": "1.0.27",
|
||||
"jsr:@std/internal@^1.0.12": "1.0.12",
|
||||
"jsr:@std/internal@^1.0.6": "1.0.12",
|
||||
"jsr:@std/path@1": "1.1.4",
|
||||
"npm:sharp@0.33": "0.33.5"
|
||||
},
|
||||
"jsr": {
|
||||
"@std/assert@1.0.13": {
|
||||
"integrity": "ae0d31e41919b12c656c742b22522c32fb26ed0cba32975cb0de2a273cb68b29",
|
||||
"dependencies": [
|
||||
"jsr:@std/internal@^1.0.6"
|
||||
]
|
||||
},
|
||||
"@std/cli@1.0.27": {
|
||||
"integrity": "eba97edd0891871a7410e835dd94b3c260c709cca5983df2689c25a71fbe04de"
|
||||
},
|
||||
"@std/internal@1.0.12": {
|
||||
"integrity": "972a634fd5bc34b242024402972cd5143eac68d8dffaca5eaa4dba30ce17b027"
|
||||
},
|
||||
"@std/path@1.1.4": {
|
||||
"integrity": "1d2d43f39efb1b42f0b1882a25486647cb851481862dc7313390b2bb044314b5",
|
||||
"dependencies": [
|
||||
"jsr:@std/internal@^1.0.12"
|
||||
]
|
||||
}
|
||||
},
|
||||
"npm": {
|
||||
"@emnapi/runtime@1.8.1": {
|
||||
"integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==",
|
||||
"dependencies": [
|
||||
"tslib"
|
||||
]
|
||||
},
|
||||
"@img/sharp-darwin-arm64@0.33.5": {
|
||||
"integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==",
|
||||
"optionalDependencies": [
|
||||
"@img/sharp-libvips-darwin-arm64"
|
||||
],
|
||||
"os": ["darwin"],
|
||||
"cpu": ["arm64"]
|
||||
},
|
||||
"@img/sharp-darwin-x64@0.33.5": {
|
||||
"integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==",
|
||||
"optionalDependencies": [
|
||||
"@img/sharp-libvips-darwin-x64"
|
||||
],
|
||||
"os": ["darwin"],
|
||||
"cpu": ["x64"]
|
||||
},
|
||||
"@img/sharp-libvips-darwin-arm64@1.0.4": {
|
||||
"integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==",
|
||||
"os": ["darwin"],
|
||||
"cpu": ["arm64"]
|
||||
},
|
||||
"@img/sharp-libvips-darwin-x64@1.0.4": {
|
||||
"integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==",
|
||||
"os": ["darwin"],
|
||||
"cpu": ["x64"]
|
||||
},
|
||||
"@img/sharp-libvips-linux-arm64@1.0.4": {
|
||||
"integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==",
|
||||
"os": ["linux"],
|
||||
"cpu": ["arm64"]
|
||||
},
|
||||
"@img/sharp-libvips-linux-arm@1.0.5": {
|
||||
"integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==",
|
||||
"os": ["linux"],
|
||||
"cpu": ["arm"]
|
||||
},
|
||||
"@img/sharp-libvips-linux-s390x@1.0.4": {
|
||||
"integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==",
|
||||
"os": ["linux"],
|
||||
"cpu": ["s390x"]
|
||||
},
|
||||
"@img/sharp-libvips-linux-x64@1.0.4": {
|
||||
"integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==",
|
||||
"os": ["linux"],
|
||||
"cpu": ["x64"]
|
||||
},
|
||||
"@img/sharp-libvips-linuxmusl-arm64@1.0.4": {
|
||||
"integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==",
|
||||
"os": ["linux"],
|
||||
"cpu": ["arm64"]
|
||||
},
|
||||
"@img/sharp-libvips-linuxmusl-x64@1.0.4": {
|
||||
"integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==",
|
||||
"os": ["linux"],
|
||||
"cpu": ["x64"]
|
||||
},
|
||||
"@img/sharp-linux-arm64@0.33.5": {
|
||||
"integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==",
|
||||
"optionalDependencies": [
|
||||
"@img/sharp-libvips-linux-arm64"
|
||||
],
|
||||
"os": ["linux"],
|
||||
"cpu": ["arm64"]
|
||||
},
|
||||
"@img/sharp-linux-arm@0.33.5": {
|
||||
"integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==",
|
||||
"optionalDependencies": [
|
||||
"@img/sharp-libvips-linux-arm"
|
||||
],
|
||||
"os": ["linux"],
|
||||
"cpu": ["arm"]
|
||||
},
|
||||
"@img/sharp-linux-s390x@0.33.5": {
|
||||
"integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==",
|
||||
"optionalDependencies": [
|
||||
"@img/sharp-libvips-linux-s390x"
|
||||
],
|
||||
"os": ["linux"],
|
||||
"cpu": ["s390x"]
|
||||
},
|
||||
"@img/sharp-linux-x64@0.33.5": {
|
||||
"integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==",
|
||||
"optionalDependencies": [
|
||||
"@img/sharp-libvips-linux-x64"
|
||||
],
|
||||
"os": ["linux"],
|
||||
"cpu": ["x64"]
|
||||
},
|
||||
"@img/sharp-linuxmusl-arm64@0.33.5": {
|
||||
"integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==",
|
||||
"optionalDependencies": [
|
||||
"@img/sharp-libvips-linuxmusl-arm64"
|
||||
],
|
||||
"os": ["linux"],
|
||||
"cpu": ["arm64"]
|
||||
},
|
||||
"@img/sharp-linuxmusl-x64@0.33.5": {
|
||||
"integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==",
|
||||
"optionalDependencies": [
|
||||
"@img/sharp-libvips-linuxmusl-x64"
|
||||
],
|
||||
"os": ["linux"],
|
||||
"cpu": ["x64"]
|
||||
},
|
||||
"@img/sharp-wasm32@0.33.5": {
|
||||
"integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==",
|
||||
"dependencies": [
|
||||
"@emnapi/runtime"
|
||||
],
|
||||
"cpu": ["wasm32"]
|
||||
},
|
||||
"@img/sharp-win32-ia32@0.33.5": {
|
||||
"integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==",
|
||||
"os": ["win32"],
|
||||
"cpu": ["ia32"]
|
||||
},
|
||||
"@img/sharp-win32-x64@0.33.5": {
|
||||
"integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==",
|
||||
"os": ["win32"],
|
||||
"cpu": ["x64"]
|
||||
},
|
||||
"color-convert@2.0.1": {
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dependencies": [
|
||||
"color-name"
|
||||
]
|
||||
},
|
||||
"color-name@1.1.4": {
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"color-string@1.9.1": {
|
||||
"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
|
||||
"dependencies": [
|
||||
"color-name",
|
||||
"simple-swizzle"
|
||||
]
|
||||
},
|
||||
"color@4.2.3": {
|
||||
"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
|
||||
"dependencies": [
|
||||
"color-convert",
|
||||
"color-string"
|
||||
]
|
||||
},
|
||||
"detect-libc@2.1.2": {
|
||||
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="
|
||||
},
|
||||
"is-arrayish@0.3.4": {
|
||||
"integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA=="
|
||||
},
|
||||
"semver@7.7.4": {
|
||||
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
|
||||
"bin": true
|
||||
},
|
||||
"sharp@0.33.5": {
|
||||
"integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==",
|
||||
"dependencies": [
|
||||
"color",
|
||||
"detect-libc",
|
||||
"semver"
|
||||
],
|
||||
"optionalDependencies": [
|
||||
"@img/sharp-darwin-arm64",
|
||||
"@img/sharp-darwin-x64",
|
||||
"@img/sharp-libvips-darwin-arm64",
|
||||
"@img/sharp-libvips-darwin-x64",
|
||||
"@img/sharp-libvips-linux-arm",
|
||||
"@img/sharp-libvips-linux-arm64",
|
||||
"@img/sharp-libvips-linux-s390x",
|
||||
"@img/sharp-libvips-linux-x64",
|
||||
"@img/sharp-libvips-linuxmusl-arm64",
|
||||
"@img/sharp-libvips-linuxmusl-x64",
|
||||
"@img/sharp-linux-arm",
|
||||
"@img/sharp-linux-arm64",
|
||||
"@img/sharp-linux-s390x",
|
||||
"@img/sharp-linux-x64",
|
||||
"@img/sharp-linuxmusl-arm64",
|
||||
"@img/sharp-linuxmusl-x64",
|
||||
"@img/sharp-wasm32",
|
||||
"@img/sharp-win32-ia32",
|
||||
"@img/sharp-win32-x64"
|
||||
],
|
||||
"scripts": true
|
||||
},
|
||||
"simple-swizzle@0.2.4": {
|
||||
"integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==",
|
||||
"dependencies": [
|
||||
"is-arrayish"
|
||||
]
|
||||
},
|
||||
"tslib@2.8.1": {
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
"dependencies": [
|
||||
"jsr:@std/assert@1",
|
||||
"jsr:@std/cli@1",
|
||||
"jsr:@std/path@1",
|
||||
"npm:sharp@0.33"
|
||||
]
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
117
image-scale/main_test.ts
Normal file
117
image-scale/main_test.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import { assertEquals, assertRejects } from "@std/assert";
|
||||
import { basename, join } from "@std/path";
|
||||
import { getOutputPath, scaleImage } from "./main.ts";
|
||||
|
||||
const testDir = await Deno.makeTempDir();
|
||||
|
||||
Deno.test("getOutputPath - changes extension to jpg", () => {
|
||||
assertEquals(
|
||||
getOutputPath("/path/to/image.png"),
|
||||
"/path/to/image.jpg",
|
||||
);
|
||||
assertEquals(
|
||||
getOutputPath("/path/to/image.jpeg"),
|
||||
"/path/to/image.jpg",
|
||||
);
|
||||
assertEquals(
|
||||
getOutputPath("/path/to/image.jpg"),
|
||||
"/path/to/image.jpg",
|
||||
);
|
||||
});
|
||||
|
||||
Deno.test("getOutputPath - with output directory", () => {
|
||||
assertEquals(
|
||||
getOutputPath("/path/to/image.png", "/output/dir"),
|
||||
"/output/dir/image.jpg",
|
||||
);
|
||||
});
|
||||
|
||||
Deno.test("scaleImage - rejects with invalid minPixels", async () => {
|
||||
await assertRejects(
|
||||
() => scaleImage("test.png", "output.jpg", 0),
|
||||
Error,
|
||||
"minPixels must be a positive number",
|
||||
);
|
||||
|
||||
await assertRejects(
|
||||
() => scaleImage("test.png", "output.jpg", -100),
|
||||
Error,
|
||||
"minPixels must be a positive number",
|
||||
);
|
||||
});
|
||||
|
||||
Deno.test("scaleImage - processes PNG image", async () => {
|
||||
// Create a simple test PNG image (100x50 pixels)
|
||||
const inputPath = join(testDir, "test_input.png");
|
||||
const outputPath = join(testDir, "test_output.jpg");
|
||||
|
||||
// Create a test image using sharp
|
||||
await Deno.writeFile(
|
||||
inputPath,
|
||||
await (await import("sharp")).default({
|
||||
create: {
|
||||
width: 100,
|
||||
height: 50,
|
||||
channels: 3,
|
||||
background: { r: 255, g: 0, b: 0 },
|
||||
},
|
||||
})
|
||||
.png()
|
||||
.toBuffer(),
|
||||
);
|
||||
|
||||
// Scale the image with min dimension of 200px
|
||||
await scaleImage(inputPath, outputPath, 200);
|
||||
|
||||
// Verify output file exists
|
||||
const outputStat = await Deno.stat(outputPath);
|
||||
assertEquals(outputStat.isFile, true);
|
||||
|
||||
// Verify the output dimensions
|
||||
const metadata = await (await import("sharp")).default(outputPath).metadata();
|
||||
// Original: 100x50, min dimension is 50
|
||||
// Scale factor: 200/50 = 4
|
||||
// New dimensions: 400x200
|
||||
assertEquals(metadata.height, 200);
|
||||
assertEquals(metadata.width, 400);
|
||||
});
|
||||
|
||||
Deno.test("scaleImage - processes JPG image", async () => {
|
||||
const inputPath = join(testDir, "test_input2.jpg");
|
||||
const outputPath = join(testDir, "test_output2.jpg");
|
||||
|
||||
// Create a test image (80x120 pixels)
|
||||
await Deno.writeFile(
|
||||
inputPath,
|
||||
await (await import("sharp")).default({
|
||||
create: {
|
||||
width: 80,
|
||||
height: 120,
|
||||
channels: 3,
|
||||
background: { r: 0, g: 255, b: 0 },
|
||||
},
|
||||
})
|
||||
.jpeg()
|
||||
.toBuffer(),
|
||||
);
|
||||
|
||||
// Scale the image with min dimension of 240px
|
||||
await scaleImage(inputPath, outputPath, 240);
|
||||
|
||||
// Verify output file exists
|
||||
const outputStat = await Deno.stat(outputPath);
|
||||
assertEquals(outputStat.isFile, true);
|
||||
|
||||
// Verify the output dimensions
|
||||
const metadata = await (await import("sharp")).default(outputPath).metadata();
|
||||
// Original: 80x120, min dimension is 80
|
||||
// Scale factor: 240/80 = 3
|
||||
// New dimensions: 240x360
|
||||
assertEquals(metadata.width, 240);
|
||||
assertEquals(metadata.height, 360);
|
||||
});
|
||||
|
||||
// Cleanup after all tests
|
||||
addEventListener("beforeunload", async () => {
|
||||
await Deno.remove(testDir, { recursive: true });
|
||||
});
|
||||
Reference in New Issue
Block a user