Plugin ESC POS v3

Mejorar calidad de imágenes en impresora térmica

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í:

Imagen original para impresora térmica

Pero al momento de imprimirla y convertirla a blanco y negro, pierde muchos detalles:

Imagen convertida a blanco y negro sin mejorar

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:

Imagen mejorada para impresora térmica ESC POS

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.

Comparativa imagen impresora térmica con calidad mejorada

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/

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Entradas recientes

Creador de credenciales web – Aplicación gratuita

Hoy te voy a presentar un creador de credenciales que acabo de programar y que…

1 semana hace

Desplegar PWA creada con Vue 3, Vite y SQLite3 en Apache

Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…

2 semanas hace

Arquitectura para wasm con Go, Vue 3, Pinia y Vite

En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…

2 semanas hace

Vue 3 y Vite: crear PWA (Progressive Web App)

En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…

2 semanas hace

Errores de Comlink y algunas soluciones

Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…

2 semanas hace

Esperar promesa para inicializar Store de Pinia con Vue 3

En este artículo te voy a enseñar cómo usar un "top level await" esperando a…

2 semanas hace

Esta web usa cookies.