diff --git a/public/pos/epos-print.js b/public/pos/epos-print.js index ce78a98..93ffb2b 100644 --- a/public/pos/epos-print.js +++ b/public/pos/epos-print.js @@ -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 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 }; })();