// Endpoint para imprimir imágenes usando Jimp import Jimp from 'jimp' import { EposMessageBuilder } from '~/server/utils/eposBuilder' import { buildSoapEnvelope, sendToPrinter, parsePrinterResponse } from '~/server/utils/printer' export default defineEventHandler(async (event) => { try { const config = useRuntimeConfig() const body = await readBody(event) const { path, width, threshold = 128, mode = 'mono' } = body as { path?: string width?: number threshold?: number mode?: string } if (!path) { return { ok: false, error: 'path required' } } // Leer y procesar imagen const img = await Jimp.read(path) let targetWidth = width || img.bitmap.width if (targetWidth <= 0) targetWidth = img.bitmap.width const scale = targetWidth / img.bitmap.width const targetHeight = Math.max(1, Math.round(img.bitmap.height * scale)) img.resize(targetWidth, targetHeight, Jimp.RESIZE_BILINEAR) img.grayscale() // Empaquetar bits MSB first por byte const bytesPerRow = Math.ceil(targetWidth / 8) const out = Buffer.alloc(bytesPerRow * targetHeight) let outIdx = 0 for (let y = 0; y < targetHeight; y++) { let byte = 0 let bit = 7 let rowBytes = 0 for (let x = 0; x < targetWidth; x++) { const idx = (y * targetWidth + x) * 4 const rgba = img.bitmap.data const r = rgba[idx] const g = rgba[idx + 1] const b = rgba[idx + 2] const lum = 0.299 * r + 0.587 * g + 0.114 * b const isBlack = lum < threshold if (isBlack) byte |= (1 << bit) bit-- if (bit < 0) { out[outIdx++] = byte rowBytes++ byte = 0 bit = 7 } } // Rellenar bits restantes if (bit !== 7) { out[outIdx++] = byte rowBytes++ } // Rellenar a bytes completos si es necesario while (rowBytes < bytesPerRow) { out[outIdx++] = 0 rowBytes++ } } const base64 = out.toString('base64') // Construir mensaje ePOS const builder = new EposMessageBuilder() builder.imageRaw({ width: targetWidth, height: targetHeight, mode, base64 }) const soap = buildSoapEnvelope(builder.build()) const result = await sendToPrinter( soap, config.printerHost, config.printerDeviceId, parseInt(config.printerTimeoutMs) ) const { success, code } = parsePrinterResponse(result.data) return { ok: success, httpStatus: result.status, code, raw: result.data, width: targetWidth, height: targetHeight } } catch (err: any) { return { ok: false, error: err.message } } })