Traitement d'image ReactJS - NodeJS

Bonne journée.

Je passe le débriefing sur Reactjs (côté client) et Nodejs (côté serveur).

Récemment, dans mon petit projet, la question s'est posée de savoir avec quelle facilité et simplicité il est possible d'échanger des images de type client-serveur.

Aujourd'hui, nous allons apprendre à envoyer des données binaires (en particulier des images) du côté client et à les traiter sur le serveur. Bienvenue au chat.

Si votre application Web est un réseau social ou un messager ou quelque chose de similaire, vous devrez certainement travailler avec des données binaires, dans la plupart des cas, c'est du traitement d'image. Cela sera discuté.

Pour avoir une idée générale, je vais l'interpréter séquentiellement.

Jetez un oeil Ă  ce qui suit


  1. Système de nombres binaires et système de nombres décimaux
  2. Page de codes : ASCII , Unicode
  3. Bit et octet
  4. Format hexadécimal
  5. Fichier binaire
  6. Tampons et threads nodejs
  7. ArrayBuffer et Uint8Array
  8. Filereader

Système de nombres binaires et système de nombres décimaux.


Il s'agit d'un nombre qui est écrit en utilisant deux caractères: les uns et les zéros.
En termes simples, il est de 2 (base) Ă  la puissance de n (le nombre de chiffres), par exemple, le nombre 10001 a 5 chiffres:

4 chiffres = 1; 2 ^ 4 = 16;
3 chiffres = 0;
2 chiffres = 0;
1 chiffre = 0;
0 chiffre = 1; 2 ^ 0 = 1;

1-vrai - faire un calcul;
0-faux - ne calcule pas;

En conséquence, nous obtenons 16 + 1 = 17;
Avec l'opération inverse, l'ordinateur présente les données sous forme binaire.

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

Le système numérique décimal est un nombre qui est écrit en utilisant 10 caractères, de 0 à 9. Nous les utilisons tous les jours.

Le fait est qu'un ordinateur vit de sa présentation d'informations. Si nous écrivons dans notre langue maternelle ou si nous comptons en décimal, alors pour un ordinateur, tout cela est une représentation binaire. Vous demandez: «Que signifie la représentation binaire?». Comme l’a dit mon professeur d’anglais, «comme vous l’entendez, c’est écrit». L'ordinateur présente des fichiers contenant du texte ou autre, ou des calculs dans le système numérique binaire - c'est la représentation binaire. La langue de la machine, le nombre "17" est - 10001.

Page de codes: ASCII, Unicode


La question se pose. C'est clair avec des chiffres, mais qu'en est-il du texte? Comment la machine convertira-t-elle le texte en binaire? Tout est simple. Pour ce faire, il existe des encodages tels que ASCII ou Unicode. Il s'agit d'un tableau simple ( page de codes ), où il y a une correspondance avec notre numéro de caractère, par exemple, le caractère "S" est le numéro 53 selon le tableau ASCII, puis l'ordinateur présentera le numéro 53 sous forme binaire - 110101.
En ce qui concerne Unicode, il s'agit d'un standard puissant qui comprend Encodage UTF-8, qui est très demandé dans l'espace Web et les systèmes de type Unix. Le principe de fonctionnement est général.

Bit et octet


Un bit est une unité de mesure des informations par un ordinateur. Et nous savons déjà comment un ordinateur représente l'information. Oui! Tu as raison. Un bit est 1 ou 0. Pour un ordinateur, 1 ou 0 est quelque chose comme un transistor, vrai ou faux. Maintenant, il n'est pas du tout difficile de comprendre ce qu'est un octet - il s'agit de 8 bits, il est aussi appelé octet (du type composé de 8).

Format hexadécimal


On passe au format "hex". Nous avons parlé du système numérique binaire, du système décimal, entre autres choses, il y a un système numérique hexadécimal, les typographes comprendront ce que je veux dire. Il s'agit d'un nombre écrit en utilisant 16 caractères, de 0 à 9 et de af. La question se pose: «Pourquoi est-ce si compliqué?». Étant donné que l'unité de mémoire est un octet de 8 bits, il est néanmoins plus pratique d'écrire sa valeur sur deux chiffres hexadécimaux. De plus, dans la norme Unicode, le numéro de caractère est généralement écrit sous forme hexadécimale en utilisant au moins 4 chiffres.
Ce format fonctionne comme suit: dans le cas d'un octet 8 bits, il divise 8 bits par sexe, c'est-à-dire 10101011 - 1010 | 1011, après convertit chaque partie en conséquence. 1010-a, 1011-b;

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

Fichier binaire


Nous passons à l'élément suivant, il est également appelé fichier binaire - c'est un tableau d'octets. Pourquoi est binaire? Les octets sont constitués de bits, c'est-à-dire de caractères d'un système de nombres binaires, d'où le nom est binaire. Absolument tous les fichiers entrent dans la catégorie des fichiers binaires, c'est-à-dire les fichiers contenant du texte, des images - tous ces fichiers sont des fichiers binaires, donc des données binaires, donc des données binaires.

Souvent, les données binaires sont générées par des caractères de page de codes ASCII, ainsi qu'au format hexadécimal, en particulier des images. Je vais vous donner un exemple. Nous avons l'image suivante:

Regarder la pièce jointe


Sa visualisation partielle est représentée par hex-agent-smith

Regarder la pièce jointe

ASCII, hex , .

ArrayBuffer et Uint8Array


ArrayBuffer - objet pour travailler avec des données binaires en javascript. Fixe la longueur de la mémoire pour travailler avec le binaire. Par exemple: new ArrayBuffer (256) - crée un objet de type tableau avec une taille de 256 octets, ni plus ni moins. Chaque octet contient des informations spécifiques. ArrayBuffer n'est pas un tableau et les méthodes de tableau ne lui sont pas applicables. Vous posez une question, comment l'utiliser? Un objet Uint8Array donne une représentation ArrayBuffer dans un nombre non signé de 8 bits, c'est-à-dire de 0 à 255.

Filereader


FileReader ? C'est le constructeur pour créer les éléments suivants:

<input type="file">

Et après?


Prenons maintenant un excellent exemple qui illustre le traitement d'image:

  1. Module 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. Module 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:


  • Pourquoi avons-nous besoin d'encodages
  • Vue gĂ©nĂ©rale des donnĂ©es binaires
  • MĂ©thode recommandĂ©e pour envoyer des octets
  • Objet tampon
  • Objet FileReader
  • ImplĂ©mentation simple sur les crochets

All Articles