This commit is contained in:
27
compressImage.js
Normal file
27
compressImage.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import fs from 'fs/promises';
|
||||||
|
import UPNG from 'upng-js';
|
||||||
|
|
||||||
|
const countUniqueColors = (data) => {
|
||||||
|
const uniqueColors = new Set();
|
||||||
|
for (let i = 0; i < data.length; i += 4) {
|
||||||
|
uniqueColors.add(`${data[i]},${data[i + 1]},${data[i + 2]},${data[i + 3]}`);
|
||||||
|
if (uniqueColors.size > 256) {
|
||||||
|
return uniqueColors.size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uniqueColors.size;
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function compressPng (filePath) {
|
||||||
|
const buffer = await fs.readFile(filePath);
|
||||||
|
const arrayBuffer = buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
||||||
|
const img = UPNG.decode(arrayBuffer);
|
||||||
|
const rgba = new Uint8Array(img.data);
|
||||||
|
const frameData = new Uint8Array(img.width * img.height * 4);
|
||||||
|
frameData.set(rgba.subarray(0, frameData.length));
|
||||||
|
const cnum = countUniqueColors(rgba) <= 256 ? 256 : 0;
|
||||||
|
const optimizedArrayBuffer = UPNG.encode([frameData.buffer], img.width, img.height, cnum, img.depth);
|
||||||
|
const optimizedBuffer = Buffer.from(optimizedArrayBuffer);
|
||||||
|
await fs.writeFile(filePath, optimizedBuffer);
|
||||||
|
return filePath;
|
||||||
|
};
|
||||||
@@ -2,12 +2,13 @@ import path from "path";
|
|||||||
import { mkdir, writeFile } from "fs/promises";
|
import { mkdir, writeFile } from "fs/promises";
|
||||||
import { fileURLToPath } from "url";
|
import { fileURLToPath } from "url";
|
||||||
import { callOllama } from "./ollamaClient.js";
|
import { callOllama } from "./ollamaClient.js";
|
||||||
|
import { compressPng } from "./compressPng.js";
|
||||||
|
|
||||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const COMFYUI_URL = process.env.COMFYUI_URL || "http://localhost:8188";
|
const COMFYUI_URL = process.env.COMFYUI_URL || "http://localhost:8188";
|
||||||
|
|
||||||
// Drawing style prefix
|
// Drawing style prefix
|
||||||
const STYLE_PREFIX = `a high-contrast, black and white pen and ink drawing, hand-drawn sketch aesthetic, very low detail, visible loose linework, expressive simple hatching for shadows, quick conceptual sketch, subtle color accent`;
|
const STYLE_PREFIX = `a high-contrast, black and white pen and ink drawing, hand-drawn sketch aesthetic, very low detail, extremely minimal, visible loose linework, expressive simple hatching for shadows, quick conceptual sketch, subtle color accent`;
|
||||||
|
|
||||||
// 1. Generate engineered visual prompt
|
// 1. Generate engineered visual prompt
|
||||||
async function generateVisualPrompt(flavor) {
|
async function generateVisualPrompt(flavor) {
|
||||||
@@ -181,6 +182,9 @@ async function generateImageViaComfyUI(prompt, filename) {
|
|||||||
|
|
||||||
console.log("Downloading image...");
|
console.log("Downloading image...");
|
||||||
const filepath = await downloadImage(comfyFilename, filename);
|
const filepath = await downloadImage(comfyFilename, filename);
|
||||||
|
|
||||||
|
console.log("Compressing PNG...");
|
||||||
|
await compressPng(filepath);
|
||||||
return filepath;
|
return filepath;
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
18
package-lock.json
generated
18
package-lock.json
generated
@@ -10,7 +10,8 @@
|
|||||||
"license": "SEE LICENSE IN README.md",
|
"license": "SEE LICENSE IN README.md",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dotenv": "^17.2.1",
|
"dotenv": "^17.2.1",
|
||||||
"puppeteer": "^24.17.1"
|
"puppeteer": "^24.17.1",
|
||||||
|
"upng-js": "^2.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.34.0",
|
"@eslint/js": "^9.34.0",
|
||||||
@@ -1475,6 +1476,12 @@
|
|||||||
"node": ">= 14"
|
"node": ">= 14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pako": {
|
||||||
|
"version": "1.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
|
||||||
|
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
|
||||||
|
"license": "(MIT AND Zlib)"
|
||||||
|
},
|
||||||
"node_modules/parent-module": {
|
"node_modules/parent-module": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||||
@@ -1871,6 +1878,15 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"node_modules/upng-js": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/upng-js/-/upng-js-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-d3xzZzpMP64YkjP5pr8gNyvBt7dLk/uGI67EctzDuVp4lCZyVMo0aJO6l/VDlgbInJYDY6cnClLoBp29eKWI6g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"pako": "^1.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/uri-js": {
|
"node_modules/uri-js": {
|
||||||
"version": "4.4.1",
|
"version": "4.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
||||||
|
|||||||
@@ -13,7 +13,8 @@
|
|||||||
"description": "",
|
"description": "",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dotenv": "^17.2.1",
|
"dotenv": "^17.2.1",
|
||||||
"puppeteer": "^24.17.1"
|
"puppeteer": "^24.17.1",
|
||||||
|
"upng-js": "^2.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.34.0",
|
"@eslint/js": "^9.34.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user