diff --git a/compressImage.js b/compressImage.js new file mode 100644 index 0000000..c4c4567 --- /dev/null +++ b/compressImage.js @@ -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; +}; diff --git a/imageGenerator.js b/imageGenerator.js index 6dc3b99..b030d53 100644 --- a/imageGenerator.js +++ b/imageGenerator.js @@ -2,12 +2,13 @@ import path from "path"; import { mkdir, writeFile } from "fs/promises"; import { fileURLToPath } from "url"; import { callOllama } from "./ollamaClient.js"; +import { compressPng } from "./compressPng.js"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const COMFYUI_URL = process.env.COMFYUI_URL || "http://localhost:8188"; // 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 async function generateVisualPrompt(flavor) { @@ -181,6 +182,9 @@ async function generateImageViaComfyUI(prompt, filename) { console.log("Downloading image..."); const filepath = await downloadImage(comfyFilename, filename); + + console.log("Compressing PNG..."); + await compressPng(filepath); return filepath; } catch (err) { diff --git a/package-lock.json b/package-lock.json index e52ee48..3ad9a99 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,8 @@ "license": "SEE LICENSE IN README.md", "dependencies": { "dotenv": "^17.2.1", - "puppeteer": "^24.17.1" + "puppeteer": "^24.17.1", + "upng-js": "^2.1.0" }, "devDependencies": { "@eslint/js": "^9.34.0", @@ -1475,6 +1476,12 @@ "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": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -1871,6 +1878,15 @@ "license": "MIT", "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": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", diff --git a/package.json b/package.json index f612433..d71f6ed 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "description": "", "dependencies": { "dotenv": "^17.2.1", - "puppeteer": "^24.17.1" + "puppeteer": "^24.17.1", + "upng-js": "^2.1.0" }, "devDependencies": { "@eslint/js": "^9.34.0",