Extraer Texto de Imagen Javascript

Para crear un extractor de imagen a texto usando JavaScript sin depender de API externas, vamos a usar la biblioteca Tesseract.js, que es un puerto de JavaScript del motor Tesseract OCR. Esto nos va a permitir realizar el reconocimiento óptico de caracteres directamente en el navegador o en un entorno Node.js. Para este tutorial sobre extraer texto de imagen, lo haremos usando javascript en vez de Node.js.

Crear la base con el input para subir la imagen

Nuestra base para la aplicacion sera bastante simple. Vamos a crear un titulo para la aplicacion, y luego dos contenedores; uno con el input para subir y/o seleccionar la imagen para extraer el texto, y otro con opciones para poder descargar el texto extraido usando variedad de extensiones de texto segun el interes de usuario.

Ademas de estos, vamos a crear un contenedor en el que presentaremos el resultado de la extraccion. En este caso el texto extraido de la imagen.

Para poder acceder al contenido HTML desde JavaScript vamos a estar usando id en cada contenedor, input, y botones. Para este tutorial vamos a permitir la descarga en tres formatos: documentos simple .txt, documento word .doc, y documento .pdf.

<h1>Image to Text Extractor</h1>
    <div id="dwlop">
        <div>
            <fieldset>
                <legend>Select image upload</legend>
                <div>
                    <label><input type="radio" id="upload" name="imginput" value="upload" checked /> Upload</label>
                </div>
              <div>
                    <input type="file" id="imageUpload" accept="image/*" aria-label="Selecciona una imagen">
                </div>
            </fieldset>           
            
        </div>
        <div>
            <fieldset style="padding: 15px;">
                <legend>Download</legend>
                <label for="format">Seleccion el Formato:</label><br/>
                <select id="format">
                    <option value="txt">TXT</option>
                    <option value="doc">Doc</option>
                    <option value="pdf">PDF</option>
                </select>
                <button id="downloadBtn" disabled>Descargar</button>
            </fieldset>
        </div>
    </div>
    <div id="output"></div>

Agregar estilo a la pagina web

Para el estilo, agregaremos algo simple, sin muchos lujos, con el proposito de presentar solamente el funcionamiento del codigo. Al finalizar el estilo, el boton de descarga estara desabilitado a proposito. Esto permitira luego ser activado usando JavaScript solo cuando la imagen sea subida y el texto extraido.

<style>
        body{text-align: center;}
        #dwlop{display: inline-flex; margin: 30px auto 10px auto; align-items: center;flex-wrap: wrap; justify-content: space-around;}
        #output{margin: 10px auto; width: fit-content; font-size: x-large;}
        fieldset{text-align: left;border-radius: 5px;}
        fieldset #imageUpload{margin: 5px auto;}
        #processUrl{background-color: transparent; cursor: pointer;font-weight: 700;display:contents;}
        #processUrl:hover{color: #CC0003; }
    </style>

Como hacer un script para extaer texto de la imagen con javascript?

Para hacer un script para extaer texto de imagen con JavaScript, vamos a hacer uso de librerias como Tesseract. Ademas, debido a que tenemos la opcion de descargar el texto como pdf, vamos a usar la libreria jsPDF para generar el archivo PDF con el contenido extraido de la imagen.

1. Agrega las librerias necesarias

Vamos a comenzar agregando las librerias Tesseract y jsPDF. La primera nos va a permitir extraer el texto dentro de una imagen, la otra libreria nos permitira exportar el texto directo a un archivo pdf.

<script src="https://cdn.jsdelivr.net/npm/tesseract.js@2.1.1/dist/tesseract.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>

2. Declarar las variables

Luego comenzamos a declarar las variables que vamos a usar:

<script>
        let addImage = document.getElementById('imageUpload'),
            processUrl = document.getElementById('processUrl'),
            dwlop = document.getElementById('dwlop'),
            downloadBtn = document.getElementById('downloadBtn'),
            outputTXT = document.getElementById('output'),
            uploadOpt = document.querySelectorAll('input[name="imginput"]');
....
</script>

3. Un forEach para un prospecto futuro donde agregar opciones de seleccion de imagen.

Ahora agregaremos un forEach para, en caso de un futuro, podamos agregar mas botones radio para incluir mas opciones con metodos para obtener un fichero usando un input.

/* Select Radio Buttons */
        uploadOpt.forEach((el) => {
            el.onchange = function(ev){
                const value = ev.target.value;
                addImage.style.display = (value === 'upload') ? 'block' : 'none';
                // agrega la variable del contenedor que se va a mostrar, usa el ejemplo de arriba...
            };
        });
document.querySelector('input[name="imginput"]:checked').dispatchEvent(new Event('change'));

4. Como agregar Tesseract y usarlo como una funcion reutilizable

Lo siguiente sera la funcion que se hara cargo de procesar la imagen usando Tesseract. Esta funcion tiene como ventaja que podras reutilizarla en cualquier lugar que desees. La funcion tomara dos variables, la primera ‘imgSrc‘ guardara la informacion de la imagen, ‘output‘ permite visualizar el resultado en un contenedor. La opcion sobre console… sirve para saber en consola al comportamiento de la funcion m iestras se ejecuta. Si deseas, puedes eliminar tanto la parte ‘{ logger: m => console.log(m) }‘ y ‘console.error(err)‘ de la funcion, pero solo cuando ya este listo para mover el codigo hacia el servidor de produccion.

/* Tesseract function */
        function processImage(imgSrc, output){
            Tesseract.recognize(
                imgSrc,
                'eng',
                {
                    logger: m => console.log(m)
                }
            ).then(({data: {text}}) =>{
                output.innerText = text;
            }).catch(err => {
                console.error(err);
                output.innerText = 'Error Processing image. Try again.';
            });
        }

5. Como usar el evento ‘change’ para ejecutar una funcion al subir una imagen.

Ahora vamos a agregar la accion al input donde subiremos la imagen para que, una vez subida, la funcion anterior genere el texto y lo presente debajo del formulario.

// handle file upload
        addImage.addEventListener('change', function(event) {
            const file = event.target.files[0];
            if (file) {
                const reader = new FileReader();
                reader.onload = function() {
                    processImage(reader.result, outputTXT); // funcion que procesa la imagen para extraer el texto
                    downloadBtn.removeAttribute('disabled'); //esta linea permite activar el boton para descargar el texto luego de que se genere.
                };
                reader.readAsDataURL(file);
            }
                        
        });

6. Como crear una funcion que utilice con ‘switch’ para acceder a las opciones de descarga

Continuando con el codigo, vamos a generar la funcion que permitira copiar el texto a un fichero. En esta fase la funcion usara la opcion que elijamos de la seleccion y generara el fichero con la extension pertinente.

function copyAsTxt(innerContent, fort){
            const content = document.getElementById(innerContent).innerText;
            let blob, fileName;
            
            switch (fort){
                case 'txt': // exportar fichero txt
                    blob = new Blob([content], {type: 'text/plain'});
                    fileName = 'content.txt';
                    break;
                case 'doc': //exportar fichero word
                    blob = new Blob([content], {type: 'application/msword'});
                    fileName = 'content.doc';
                    break;
                case 'pdf': // usar una funcion para generar el fichero pdf
                    pdfFile(content); //funcion PDF
                    break;
                default: // opcion por defecto
                    blob = new Blob([content], {type: 'text/plain'});
                    fileName = 'content.txt';
            }
            
            // crear el link con la href, ejecutarlo y luego elimina el link
            const link = document.createElement('a');
            link.href = URL.createObjectURL(blob);
            link.download = fileName;
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }

7. Como agregarle un evento onclick a un boton y usar la funcion de copiar

Para agregar un evento onclick a un boton, vamos a usar la opcion ‘boton.onclick‘ y luego le asignaremos una funcion que ejecuta la accion onclick para descargar el fichero:

downloadBtn.onclick = function(){
            const formate = document.getElementById('format').value
            copyAsTxt('output', formate);
        };

8. Como crear una funcion simple para exportar a pdf usando jsPDF.

Por ultimo, vamos a crear la funcion para generar el pdf usando la libreria jsPDF. Dentro de la funcion vamos a usar las opciones text() para agregar el texto al documento y save() para descargar el documento pdf:

function pdfFile(content){
            const { jsPDF } = window.jspdf;
            const doc = new jsPDF();
            doc.text(content, 10, 10);
            doc.save('content.pdf');
        }

Con esto ya tenemos todo el codigo creado y podemos comenzar a extraer texto de las imagenes que subamos.