En este artículo te voy a enseñar una técnica para mejorar la calidad de las fotos impresas con una impresora térmica usando comandos ESC POS.
La mayoría de impresoras térmicas que conozco solo pueden imprimir blanco o negro (un punto quemado, o un punto sin quemar) así que es un poco complejo imprimir una imagen y mantener todos sus detalles como la iluminación o forma.
Por ejemplo, tengo la imagen de un colibrí a color y se ve así:
Pero al momento de imprimirla y convertirla a blanco y negro, pierde muchos detalles:
Es totalmente normal, pues la impresora no tiene forma de imprimir más colores además del blanco y negro. Si un color es más blanco, se convierte a blanco, y si se acerca más al negro, se convierte en negro.
Nota: la conversión de una imagen para que sea entendible por la impresora térmica no es automática, tiene todo un proceso según el algoritmo. Actualmente conozco Bit image column format, Raster bit image y NV Graphics.
Para mejorar la calidad de las imágenes en una impresora térmica podemos usar la técnica del algoritmo Floyd-Steinberg Dithering para dar la ilusión de que la imagen tiene tonos e iluminación, usando solo blanco y negro:
Aunque parezca una imagen en escala de grises (cosa que una impresora térmica no puede imprimir, pues no tiene niveles de grises) en realidad es una imagen que solo utiliza blanco y negro, pero su calidad ha mejorado bastante y se pueden apreciar muchísimos detalles.
Hemos mejorado la calidad de la fotografía que será impresa en una impresora térmica, usando solo blanco y negro. Si quieres puedes comprobar acercando la imagen y verás que solo contiene puntos blancos y negros, nada de grises. Incluso así, conserva más detalles.
Aclaración sobre la calidad
El término “calidad” puede ser subjetivo. Aquí, con “mejorar la calidad de imágenes al imprimirlas en impresoras térmicas” me refiero a conservar más detalles como la iluminación y los tonos al imprimir una fotografía en una POS printer.
Para mí, eso es mejorar la calidad de la imagen: que tenga más detalles.
Imprimiendo con calidad mejorada
Entonces básicamente el truco para que las imágenes impresas con impresoras térmicas tengan más detalles y mejor calidad es aplicar el algoritmo Floyd-Steinberg Dithering.
Si tú solo quieres imprimir imágenes con mejor calidad sin saber tantos detalles técnicos entonces dirígete a la herramienta para imprimir fotos en impresora térmica. Voy a explicar los detalles técnicos a continuación.
Código fuente para aplicar algoritmo Floyd-Steinberg Dithering en impresora térmica
Para imprimir la fotografía y aplicar el algoritmo hay que hacer una lista de operaciones para la impresora térmica y luego enviarla junto con el nombre de la impresora.
const payload = {
"serial": licencia,
"nombreImpresora": nombreImpresora,
"operaciones": [
{
"nombre": "Iniciar",
"argumentos": [
]
},
{
"nombre": "ImprimirImagenEnBase64",
"argumentos": [
fotoEnBase64,
maximoAncho,
algoritmo,
aplicarDithering
]
},
{
"nombre": "Feed",
"argumentos": [
2
]
},
]
};
En este caso estoy usando 3 operaciones: Iniciar, ImprimirImagenEnBase64 y Feed. La operación importante es la que imprime la imagen en base64. Según la documentación dice:
Convierte el texto en base64 a una imagen. La imagen codificada en base64 puede ser JPG o PNG y puede tener o no tener el “base64,”. La imagen será convertida a blanco y negro.
Si el ancho de la imagen es mayor que el máximo ancho especificado, la imagen será redimensionada para que coincida. El algoritmo se refiere al algoritmo utilizado al imprimir la imagen, que puede ser 0 para usar el método Raster Bit Image, 1 para Bit Image Column Format y 2 para NV Graphics.
Las impresoras más recientes soportan NV Graphics, las antiguas soportan Raster Bit Image e Image Column Format. Lo recomendable es que el usuario pruebe con los 3 algoritmos para encontrar el más adecuado.
Más información sobre los algoritmos: https://parzibyte.me/blog/2024/01/17/metodos-imprimir-imagenes-impresoras-termicas/.
El parámetro sobre el dithering indica si se debe aplicar el algoritmo Floyd-Steinberg-Dithering a la imagen antes de ser impresa. Es recomendado aplicarlo en fotografías, así se mantiene la iluminación y los detalles incluso al ser convertida a blanco y negro.
Más información sobre dithering: https://parzibyte.me/blog/2024/07/28/algoritmo-floyd-steinberg-dithering-golang/
La operación está así:
{
"nombre": "ImprimirImagenEnBase64",
"argumentos": [
fotoEnBase64,
maximoAncho,
algoritmo,
aplicarDithering
]
}
Así que, para aplicar la mejora de calidad, hay que especificar el último parámetro que es aplicarDithering
en true
. En este caso ese parámetro se toma de un campo modificable por el usuario:
$imprimir.addEventListener("click", async () => {
for (const foto of $fotosSeleccionadas.files) {
const imagenEnBase64 = await fileToBase64(foto);
await imprimirFoto($impresoras.value, imagenEnBase64, parseInt($algoritmo.value), $licencia.value, $maximoAncho.valueAsNumber, $aplicarDithering.checked);
}
});
Y así puedes imprimir una imagen automáticamente en tu impresora térmica enviando esa carga útil a la API HTTP local de la impresora térmica:
const imprimirFoto = async (nombreImpresora, fotoEnBase64, algoritmo, licencia, maximoAncho, aplicarDithering) => {
const payload = {
"serial": licencia,
"nombreImpresora": nombreImpresora,
"operaciones": [
{
"nombre": "Iniciar",
"argumentos": [
]
},
{
"nombre": "ImprimirImagenEnBase64",
"argumentos": [
fotoEnBase64,
maximoAncho,
algoritmo,
aplicarDithering
]
},
{
"nombre": "Feed",
"argumentos": [
2
]
},
]
};
const httpResponse = await fetch("http://localhost:8000/imprimir",
{
method: "POST",
body: JSON.stringify(payload),
});
const jsonResponse = await httpResponse.json();
if (jsonResponse.ok) {
// Everything is ok
console.log("Printed successfully");
} else {
// Error message is on message property
console.error(jsonResponse.message)
}
}
El código fuente está en GitHub, y la aplicación lista para ser usada está en este enlace. No te olvides que puedes consumir la API desde cualquier lugar leyendo la documentación.
Configurar impresora y descargar servidor HTTP a ESC POS
Para que el código funcione necesitas el servidor local de la API ESC POS ejecutándose y que tu impresora esté compartida. Por favor, sigue los pasos que aparecen en la página previamente enlazada, ya que ahí está la API unificada.
La documentación completa está en: https://parzibyte.me/http-esc-pos-desktop-docs/es/