Skip to content

Commit 994ddc0

Browse files
committed
1 parent 19f16b2 commit 994ddc0

3 files changed

Lines changed: 72 additions & 8 deletions

File tree

installation/make-electron-builder-yml.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ files.push(
105105

106106
files,
107107

108+
asarUnpack: [
109+
"node_modules/pngquant-bin/**"
110+
],
111+
108112
extraResources: await getExtraResource(),
109113

110114
fileAssociations: [

packages/project-editor/lvgl/lv_img_conv_v9/index.js

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -619,8 +619,40 @@ class LVGLImage {
619619
// Simple wrapper to call pngquant if available (uses pngquant-bin if installed)
620620
classPngQuant(ncolors=256, dither=true, execPath='', forceJS=false, forceBin=false) {
621621
let pngquantPath = null;
622+
623+
// Try to find pngquant binary by searching up the directory tree for node_modules
624+
const findPngquantBinary = () => {
625+
let searchDir = __dirname;
626+
const maxLevels = 20;
627+
const binaryName = process.platform === 'win32' ? 'pngquant.exe' : 'pngquant';
628+
629+
// First, check if we're in an Electron app and look for unpacked asar path
630+
// This takes priority because executables can't run from inside .asar archive
631+
for (let i = 0; i < maxLevels; i++) {
632+
// Check for unpacked asar path first
633+
const asarUnpackedPath = path.join(searchDir, '..', 'app.asar.unpacked', 'node_modules', 'pngquant-bin', 'vendor');
634+
const asarPngquantExe = path.join(asarUnpackedPath, binaryName);
635+
if (fs.existsSync(asarPngquantExe)) {
636+
return asarPngquantExe;
637+
}
638+
639+
// Then check regular node_modules, but skip if inside asar archive
640+
const vendorPath = path.join(searchDir, 'node_modules', 'pngquant-bin', 'vendor');
641+
const pngquantExe = path.join(vendorPath, binaryName);
642+
if (fs.existsSync(pngquantExe) && !pngquantExe.includes('.asar')) {
643+
return pngquantExe;
644+
}
645+
646+
const parentDir = path.dirname(searchDir);
647+
if (parentDir === searchDir) break; // reached filesystem root
648+
searchDir = parentDir;
649+
}
650+
651+
return null;
652+
};
653+
622654
try {
623-
pngquantPath = require('pngquant-bin');
655+
pngquantPath = findPngquantBinary();
624656
} catch (e) {
625657
pngquantPath = null;
626658
}
@@ -720,8 +752,17 @@ class LVGLImage {
720752
}
721753

722754
// resolve binary path if pngquant-bin returned an object
723-
let bin = pngquantPath || path.join(execPath, 'pngquant');
724-
if (bin && typeof bin === 'object' && bin.default) bin = bin.default;
755+
let bin = pngquantPath;
756+
if (!bin && execPath) bin = path.join(execPath, process.platform === 'win32' ? 'pngquant.exe' : 'pngquant');
757+
if (bin && typeof bin === 'object') {
758+
bin = bin.default || bin.path || null;
759+
}
760+
761+
if (!bin) {
762+
console.warn('pngquant binary path could not be resolved; falling back to JS quantization');
763+
// Fall back to JS quantization by returning null to trigger the fallback condition
764+
return null;
765+
}
725766

726767
// Handle data URIs and buffers by writing to a temporary file
727768
let inputFile = filename;
@@ -746,12 +787,21 @@ class LVGLImage {
746787
args.push(String(ncolors));
747788
args.push('--force', '--output', '-', '--', inputFile);
748789

790+
console.debug(`pngquant binary: ${bin}`);
791+
console.debug(`pngquant args: ${args.join(' ')}`);
792+
749793
const res = child_process.spawnSync(bin, args);
750794
if (res.status !== 0) {
751-
const err = res.stderr ? res.stderr.toString() : 'unknown error';
752-
throw new Error(`pngquant conversion failed: ${err}`);
795+
const err = res.stderr ? res.stderr.toString() : (res.error ? res.error.message : 'unknown error');
796+
console.warn(`pngquant conversion failed (status: ${res.status}, error: ${err}); falling back to JS quantization`);
797+
// Return null to trigger fallback to JS quantization
798+
return null;
753799
}
754800
return res.stdout;
801+
} catch (e) {
802+
console.warn(`pngquant error (${e.message}); falling back to JS quantization`);
803+
// Return null to trigger fallback to JS quantization
804+
return null;
755805
} finally {
756806
// Clean up temporary file
757807
if (tempFile && fs.existsSync(tempFile)) {
@@ -818,12 +868,22 @@ class LVGLImage {
818868
let quantResult = null;
819869
const palette_len = png.palette ? png.palette.length : 0;
820870
if (!png.palette || (!auto_cf && palette_len !== ncolors(cf))) {
821-
const q = this.classPngQuant(ncolors(cf), true, '', this.forceJSQuant, this.forceUsePngquant);
822-
const res = q.convert(filename);
871+
let q = this.classPngQuant(ncolors(cf), true, '', this.forceJSQuant, this.forceUsePngquant);
872+
let res = q.convert(filename);
873+
874+
// If pngquant failed (returned null), fall back to JS quantization
875+
if (res === null && !this.forceJSQuant) {
876+
console.warn('pngquant unavailable or failed; using JS quantization as fallback');
877+
q = this.classPngQuant(ncolors(cf), true, '', true, false); // Force JS quantization
878+
res = q.convert(filename);
879+
}
880+
823881
if (Buffer.isBuffer(res)) {
824882
png = PNG.sync.read(res, {inputHasAlpha:true});
825883
} else if (res && res.palette && res.rows) {
826884
quantResult = res; // { palette: [[r,g,b,a],..], rows: [ [idx,...], ... ], width, height }
885+
} else if (res === null) {
886+
throw new Error('both pngquant and JS quantization failed');
827887
} else {
828888
throw new Error('pngquant conversion returned unexpected result');
829889
}

packages/project-editor/lvgl/lvgl-versions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ const version_9 = {
309309
const embeddedImage = await bitmap.getEmbeddedImage();
310310

311311
try {
312-
const img = await new LVGLImage().from_png(embeddedImage, TO_IMAGE_MODE[bitmap.bpp.toString()], 0x000000, false, false, false, true);
312+
const img = await new LVGLImage().from_png(embeddedImage, TO_IMAGE_MODE[bitmap.bpp.toString()], 0x000000, false, false, false, false);
313313

314314
let result;
315315
if (binFile) {

0 commit comments

Comments
 (0)