Procesamiento de imagen ReactJS - NodeJS

Buen día.

Informes que paso en Reactjs (lado del cliente) y Nodejs (lado del servidor).

Recientemente, en mi pequeño proyecto, surgió la pregunta de cuán fácil y simple es posible intercambiar imágenes del tipo cliente-servidor.

Hoy aprenderemos cómo enviar datos binarios (específicamente imágenes) desde el lado del cliente y procesarlos en el servidor. Bienvenido a cat.

Si su aplicación web es una red social o messenger o algo similar, entonces seguramente tendrá que trabajar con datos binarios, en la mayoría de los casos es el procesamiento de imágenes. Esto será discutido.

Para tener una idea general, la interpretaré secuencialmente.

Echa un vistazo a lo siguiente


  1. Sistema de números binarios y sistema de números decimales
  2. Página de códigos : ASCII , Unicode
  3. Bit y byte
  4. Formato hexadecimal
  5. Archivo binario
  6. Buffer y subprocesos nodejs
  7. ArrayBuffer y Uint8Array
  8. Lector de archivos

Sistema de números binarios y sistema de números decimales.


Este es un número que se escribe con dos caracteres: unos y ceros.
En términos simples, es 2 (base) a la potencia de n (el número de dígitos), por ejemplo, el número 10001 tiene 5 dígitos:

4 dígitos = 1; 2 ^ 4 = 16;
3 dígitos = 0;
2 dígitos = 0;
1 dígito = 0;
0 dígitos = 1; 2 ^ 0 = 1;

1-verdadero: hacer un cálculo;
0-falso: no calcular;

Como resultado, obtenemos 16 + 1 = 17;
Con la operación inversa, la computadora presenta los datos en forma binaria.

const num = 17; //  
const binNum = num.toString(2); //    
const initNum = parseInt(binNum, 2); //  

El sistema de números decimales es un número que se escribe con 10 caracteres, de 0 a 9. Los usamos todos los días.

El hecho es que una computadora vive de su presentación de información. Si escribimos en nuestro idioma nativo o contamos en decimal, entonces para una computadora todo esto es una representación binaria. Usted pregunta: "¿Qué significa la representación binaria?". Como dijo mi profesor de inglés, "tal como lo escuchas, está escrito". La computadora presenta archivos que contienen texto o no, o cualquier cálculo en el sistema de números binarios: esta es la representación binaria. El idioma de la máquina, el número "17" es - 10001.

Página de códigos: ASCII, Unicode


Surge la pregunta. Está claro con los números, pero ¿qué pasa con el texto? ¿Cómo convertirá la máquina el texto a binario? Todo es simple Para hacer esto, hay codificaciones como ASCII o Unicode. Esta es una tabla simple ( página de códigos ), donde hay una asignación a nuestro número de caracteres, por ejemplo, el carácter "S" es el número 53 según la tabla ASCII, luego la computadora presentará el número 53 en forma binaria - 110101.
Con respecto a Unicode, este es un estándar poderoso que incluye Codificación UTF-8, que tiene una gran demanda en el espacio web y en sistemas unix. El principio de funcionamiento es general.

Bit y byte


Un bit es una unidad de medida de información por una computadora. Y ya sabemos cómo una computadora representa la información. ¡Si! Tienes razón. Un bit es 1 o 0. Para una computadora, 1 o 0 es algo así como un transistor, verdadero o falso. Ahora no es nada difícil entender qué es un byte: son 8 bits, también se llama octeto (el tipo consta de 8).

Formato hexadecimal


Pasamos al formato "hexadecimal". Hablamos sobre el sistema de números binarios, el sistema decimal, entre otras cosas, hay un sistema de números hexadecimales, los tipógrafos entenderán lo que quiero decir. Este es un número que se escribe con 16 caracteres, de 0 a 9 y de af. Surge la pregunta: "¿Por qué es tan complicado?". Como la unidad de memoria es un byte de 8 bits, es más conveniente escribir su valor en dos dígitos hexadecimales. Además, en el estándar Unicode, el número de caracteres generalmente se escribe en forma hexadecimal con al menos 4 dígitos.
Este formato funciona de la siguiente manera: en el caso de un byte de 8 bits, divide 8 bits por género, es decir, 10101011 - 1010 | 1011, después convierte cada parte en consecuencia. 1010-a, 1011-b;

const num = 196; //  
const hexNum = num.toString(16); //   hex 
const initNum = parseInt(hexNum, 16); //     -  

Archivo binario


Pasamos al siguiente elemento, también se llama archivo binario: es una matriz de bytes. ¿Por qué es binario? Los bytes consisten en bits, es decir, caracteres de un sistema de números binarios, de ahí que el nombre sea binario. Absolutamente todos los archivos encajan en la categoría de archivo binario, es decir, archivos que contienen texto, imágenes; todos estos son archivos binarios, por lo tanto, datos binarios, por lo tanto, datos binarios.

A menudo, los datos binarios se emiten mediante caracteres de página de códigos ASCII, así como en formato hexadecimal, en imágenes particulares. Daré un ejemplo. Tenemos la siguiente imagen:

Ver archivo adjunto


Su visualización parcial se representa como hex-agent-smith

Ver archivo adjunto

El lado derecho de los caracteres son caracteres ASCII, el lado izquierdo es solo el formato hexadecimal, convertido de código binario.

ArrayBuffer y Uint8Array


ArrayBuffer : objeto para trabajar con datos binarios en javascript. Corrige la longitud de la memoria para trabajar con el binario. Por ejemplo: nuevo ArrayBuffer (256) : crea un objeto tipo matriz con un tamaño de 256 bytes, ni más, ni menos. Cada byte tiene información específica. ArrayBuffer no es una matriz y los métodos de la matriz no le son aplicables. Usted hace una pregunta, ¿cómo usarlo? Un objeto Uint8Array proporciona una representación ArrayBuffer en un número de 8 bits sin signo, es decir, de 0 a 255.

Lector de archivos


FileReader ? Este es el constructor para crear lo siguiente:

<input type="file">

¿Que sigue?


Ahora considere un gran ejemplo que demuestra el procesamiento de imágenes:

  1. Módulo ReactJS
    import React, {useState, useRef, useCallback} from 'react';
    import axios from 'axios';
    
    export const UPLOAD_AVATAR = 'http://localhost:8080/api/upload_avatar';
    
    function App() {
      //   ref   FileReader
      const fileRef = useRef(null);
      const [ loading, setLoading ] = useState(false);
    
      const handleSubmit = useCallback( event => {
        event.preventDefault();
    
        const fetchData = async (uint8Array) => {
          try {
            const response = await axios({
              method: 'post',
              url: UPLOAD_AVATAR,
              data: [...uint8Array] //    JSON,   
            });
    
            setLoading(false);
            console.log(response);
          } catch (e) {
            console.error(e.message, 'function handleSubmit')
          }
        };
    
        if(!fileRef.current) return void null;
    
        const reader = new FileReader();
        reader.onloadend = () => {
          const uint8Array = new Uint8Array(reader.result);
          setLoading(true);
          fetchData(uint8Array);
        };
    
    
        //  
        reader.readAsArrayBuffer(fileRef.current[0]);
    
        //  reader.readAsBinaryString(fileRef.current[0]) 
        //  MDN,
        //      File API specification, 
        //    
        //  ,     
        //  readAsArrayBuffer
        // https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsBinaryString
      }, []);
    
      const nodeDom = (
        <form onSubmit={handleSubmit}>
          <div>
            <input
              onChange={e => fileRef.current = e.target.files}
              accept="image/*"
              type="file"
              id="button-file"
            />
          </div>
          <button type="submit">{loading ? '...' : ''}</button>
        </form>
      );
    
      return nodeDom
    }
    
    export default App;
    
                   

  2. Módulo ExpressJS
    const express = require("express");
    const cors = require("cors");
    
    const crypto = require('crypto');
    const fs = require('fs');
    
    const PORT = 8080;
    
    const app = express();
    
    app.use(express.static("public"));
    app.use(express.json({ limit: "50mb" }));
    app.use(cors());
    
    app.post("/api/upload_avatar", (req, res) => {
      console.log(req.body);
      const randomString = crypto.randomBytes(5).toString('hex');
      const stream = fs.createWriteStream(`./public/images/${randomString}.png`);
    
      stream.on('finish', function () {
        console.log('file has been written');
        res.end('file has been written');
      });
    
      stream.write(Buffer.from(req.body), 'utf-8');
      stream.end();
    });
    
    app.listen(PORT, () => console.log(`Server running at ${PORT}`));
    
                  


Total:


  • ¿Por qué necesitamos codificaciones?
  • Vista general de datos binarios.
  • Forma recomendada de enviar bytes
  • Objeto tampón
  • FileReader Object
  • Implementación simple en ganchos

All Articles