feat(pos): add canvas-based logo rasterization for ePOS-Print
This commit is contained in:
parent
2ea76f9d9a
commit
4f54051b66
1 changed files with 45 additions and 1 deletions
|
|
@ -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 };
|
||||
})();
|
||||
|
|
|
|||
Loading…
Reference in a new issue