En este post voy a presentarte una herramienta para poder imprimir imágenes grandes en una impresora térmica ESC POS dividiendo las imágenes en fragmentos pequeños que no superen el ancho del papel térmico.

Una vez impresos ya puedes unirlos como tú prefieras. De este modo podrás imprimir imágenes de cualquier tamaño separadas en fragmentos que quepan correctamente en el papel térmico.

Otras descripciones que puede tener esta herramienta:
- Imprimir imagen completa en impresora térmica separándola en fragmentos
- Cortar imágenes para imprimirla en impresora térmica
- Cortar imagen en pedazos con JavaScript
Convertir File a imagen
Cuando el usuario elige un archivo usando el elemento <input type="file">
tenemos los archivos en $elemento.files que es un array de tipo File.
No necesitamos un File, necesitamos un ImageBitmap así que convertimos
el File a ImageBitmap con createImageBitmap
usando el primer archivo seleccionado ($imagen.files[0]):
$imagen.addEventListener("change", async () => {
const imagen = await createImageBitmap($imagen.files[0]);
$alto.value = imagen.height;
generarCanvasPrevisualizaciones();
})
Dividir imagen en fragmentos
Y después se generan varios elementos de tipo canvas
que contendrán un fragmento de la imagen completa. Estos fragmentos
son importantes porque más adelante podremos descargarlos e imprimirlos
ya sea en conjunto o individualmente.
Necesitamos hacer un ciclo para dividir la imagen
en varios fragmentos, y en cada paso es necesario
calcular las coordenadas x e y de inicio y fin, pues
necesitamos un pedazo de la imagen para imprimirla más adelante
en una impresora térmica.
for (let yInicio = 0; yInicio < imagen.height; yInicio += altoMaximoEstablecidoPorUsuario) {
let ancho = anchoMaximoEstablecidoPorUsuario;
let alto = altoMaximoEstablecidoPorUsuario;
if (xInicio + anchoMaximoEstablecidoPorUsuario > imagen.width) {
ancho = imagen.width - xInicio;
}
if (yInicio + altoMaximoEstablecidoPorUsuario > imagen.height) {
alto = imagen.height - yInicio;
}
const xFin = xInicio + ancho;
const yFin = yInicio + alto;
Una vez que tenemos las coordenadas entonces dibujamos un fragmento
de la imagen en un canvas recién creado con document.createElement:
const $canvasFragmento = document.createElement("canvas");
$canvasFragmento.width = ancho;
$canvasFragmento.height = alto;
const contextoCanvasRecienCreado = $canvasFragmento.getContext("2d");
contextoCanvasRecienCreado.drawImage(imagen, xInicio, yInicio, ancho, alto, 0, 0, ancho, alto);
Así es como logramos dividir la imagen completa en fragmentos pequeños. Además de dibujar el pedazo de la imagen también añadimos unos enlaces para descargar e imprimr cada uno de ellos.
Imprimir fragmentos de imagen en impresora térmica
El plugin de impresión permite imprimir imágenes en base64 así que simplemente mapeamos cada canvas a base64 y lo ajustamos para que respete la API de impresión ESC POS:
const canvasComoOperaciones = coleccionDeCanvas.map($canvas => {
return {
nombre: "ImprimirImagenEnBase64",
argumentos: [
$canvas.toDataURL(),
$canvas.width,
0,
true
]
};
})
Veamos la función que imprime un canvas de JavaScript en una impresora térmica.
Dicha función se llama imprimirColeccionDeCanvas y se comunica
con mi plugin para impresoras térmicas
para imprimir una colección de imágenes.
Tenemos una colección de elementos del DOM de
tipo canvas. Podemos convertir dicho canvas a
una imagen en base64 usando toDataURL.
He hecho la función de esta manera para que sirva para imprimir una o varias imágenes en el mismo código, y queda así:
const imprimirColeccionDeCanvas = (coleccionDeCanvas) => {
const nombreImpresora = $impresoras.value;
return new Promise(async (resolve, reject) => {
const operaciones = [
{
"nombre": "Iniciar",
"argumentos": []
},
];
const canvasComoOperaciones = coleccionDeCanvas.map($canvas => {
return {
nombre: "ImprimirImagenEnBase64",
argumentos: [
$canvas.toDataURL(),
$canvas.width,
0,
true
]
};
})
operaciones.push(...canvasComoOperaciones);
operaciones.push(
// Un Feed por si no tienen cortador
{
"nombre": "Feed",
"argumentos": [1],
},
{
"nombre": "Corte",
"argumentos": [
1
]
}
)
const cargaUtil = {
"serial": "",
nombreImpresora,
operaciones,
};
try {
registrarMensaje("Imprimiendo ...");
const respuestaHttp = await fetch("http://localhost:8000/imprimir",
{
method: "POST",
body: JSON.stringify(cargaUtil),
});
const respuestaComoJson = await respuestaHttp.json();
if (respuestaComoJson.ok) {
registrarMensaje("Impreso correctamente");
resolve();
} else {
// El error está en la propiedad message
reject(respuestaComoJson)
}
} catch (e) {
reject(e)
}
})
}
Después de eso invoco a la función imprimirColeccionDeCanvas cuando
se quieren imprimir todas las imágenes:
const todosLosCanvas = document.querySelectorAll("canvas");
$imprimir.textContent = "Imprimiendo...";
await imprimirColeccionDeCanvas([...todosLosCanvas]);
O cuando solo se quiere imprimir una:
$pImprimir.addEventListener("click", async () => {
await imprimirColeccionDeCanvas([$canvasFragmento]);
})
De esta manera:
- Tenemos una imagen en resolución grande que no cabe en una impresora térmica
- Dividimos la imagen en fragmentos delgados que no superan el ancho del papel térmico
- Imprimimos cada imagen en una impresora térmica usando Dithering y ESC POS
Por cierto, esta herramienta también te permite dividir las imágenes y guardarlas para cualquier otra cosa. No es obligatorio imprimirlas en una impresora térmica, puedes usar la app como cortadora de imágenes y descargar todos los fragmentos en un zip.
Usar herramienta
Si quieres imprimir una imagen en tamaño completo dividida en pedazos en una impresora térmica necesitas:
- Instalar tu impresora como genérica y compartirla
- Descargar y ejecutar el plugin 3.5.2: http://parzibyte.me/static/ESC_POS_3.5.2_W64.zip
- Acceder a la siguiente web app en línea y dar los permisos necesarios: https://parzibyte.me/apps/cortador-imagenes-esc-pos/
Código fuente
El código fuente completo está en GitHub: https://github.com/parzibyte/cortador-imagenes-esc-pos
Necesitas Node v24.5.0. Una vez que hayas descargado el repositorio ejecuta:
npm installnpm run dev- Cuando estés listo para distribuir ejecuta
npm run buildy distribuye la carpeta dist