feat(pos): add canvas-based logo rasterization for ePOS-Print

This commit is contained in:
Dave 2026-09-03 17:52:47 +02:00
parent 2ea76f9d9a
commit 4f54051b66

View file

@ -24,5 +24,49 @@ window.EposPrint = (function () {
localStorage.setItem(SETTINGS_KEY, JSON.stringify(settings));
}
return { getSettings, setSettings };
// Rasterize a same-origin image into the packed 1bpp bitmap the
// ePOS-Print <image> tag expects. targetWidth must be a multiple of
// 8; 384 is the width verified against the shop's TM-T20II.
function imageToRaster(url, targetWidth) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
const targetHeight = Math.round(img.height * targetWidth / img.width);
const canvas = document.createElement('canvas');
canvas.width = targetWidth;
canvas.height = targetHeight;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, targetWidth, targetHeight);
ctx.drawImage(img, 0, 0, targetWidth, targetHeight);
let imageData;
try {
imageData = ctx.getImageData(0, 0, targetWidth, targetHeight);
} catch (e) {
reject(new Error('Could not read logo pixels (cross-origin image?): ' + e.message));
return;
}
const data = imageData.data;
const rowBytes = Math.ceil(targetWidth / 8);
const packed = new Uint8Array(rowBytes * targetHeight);
for (let y = 0; y < targetHeight; y++) {
for (let x = 0; x < targetWidth; x++) {
const i = (y * targetWidth + x) * 4;
const luminance = data[i] * 0.3 + data[i + 1] * 0.59 + data[i + 2] * 0.11;
const alpha = data[i + 3];
if (alpha > 128 && luminance < 128) {
packed[y * rowBytes + (x >> 3)] |= 0x80 >> (x % 8);
}
}
}
let binary = '';
for (let i = 0; i < packed.length; i++) binary += String.fromCharCode(packed[i]);
resolve({ width: targetWidth, height: targetHeight, base64: btoa(binary) });
};
img.onerror = () => reject(new Error('Could not load logo image: ' + url));
img.src = url;
});
}
return { getSettings, setSettings, imageToRaster };
})();