Made a picture recognition software, applied to the image stream, preview, Blob, Base64, and type conversion and other technologies. These techniques are essential for image-related development, and this time, let’s play with Image stream!

1. Common Scenarios

Let’s take a look at the use of images:

  • Upload via input;
  • File drag upload;
  • Picture preview;
  • Image data storage;
  • Third-party interfaces are required.

Of course, the actual application is far more complicated than this, but if we have mastered the core idea, then it is nothing more than “picture stream” capture and conversion, let us step into the next!

Second, talk about picture flow

The above mentioned “picture stream” is actually a binary stream to represent the image, also known as “binary image”.

Computer storage is physically binary, so the difference between a text file and a binary file is not physical, but logical.


  1. Binary files save space and store character data in the same way as normal storage. But when it comes to storing numbers, especially real numbers, binary is more space-efficient;
  2. The data in memory is stored in binary format, so it is faster to use binary to save to a file. If stored as a text file, a conversion process is required. When there is a large amount of data, there will be a significant speed difference between the two;
  3. Involving some more accurate data, the use of binary storage will not cause the loss of effective bits;

See here, I believe you have a certain understanding of the picture flow. Since storage is mentioned, I would like to add a few details about how images can be stored in the back end:

  • First: pictures can be stored in the form of independent files in the server’s designated folder, and then the path into the database field;
  • Second: the image into a binary stream, directly stored in the databaseImageIn the type field;

What is a FileReader?

The FileReader object allows a Web application to asynchronously read the contents of a File (or raw data buffer) stored on the user’s computer, using a File or Blob object to specify which File or data to read.

The File object can be a FileList object returned by the user after selecting a File on an element, a DataTransfer object generated by a drag-and-drop operation, or an HTMLCanvasElement executed on it The mozGetAsFile() method returns the result.

There’s a lot of gobbledygook, but all you need to know is that it reads files.


  • FileReader.error(read only) : oneDOMException, indicating an error occurred while reading the file;
  • FileReader.readyState(read-only) : indicatesFileReaderNumber of states. The values are as follows:
    • EMPTY0 has not loaded any data yet.
    • LOADING1 Data is being loaded.
    • DONE2 All read requests have been completed.
  • FileReader.result(read only) : Contents of a file. This property is valid only after the read operation is complete, and the format of the data depends on which method is used to initiate the read operation.

There are also several event handlers:

  • FileReader.onabort: handlingabortEvents. This event is emitted when the read operation is interrupted.
  • FileReader.onerror: handlingerrorEvents. This event is emitted when an error occurs in a read operation.
  • FileReader.onload: handlingloadEvents. This event is emitted when the read operation is complete.
  • FileReader.onloadstart: handlingloadstartEvents. This event is emitted when the read operation begins.
  • FileReader.onloadend: handlingloadendEvents. This event is emitted at the end of a read operation (either successful or failed).
  • FileReader.onprogress: handlingprogressEvents. The event is readingBlobWhen triggered.

Methods can be used as follows:

  • FileReader.abort(): Aborts the read operation. On the return,readyStateProperties forDONE.
  • FileReader.readAsArrayBuffer(): starts reading the specifiedBlobThe content of. Once that’s done,resultProperty will contain oneArrayBufferTo represent file data;
  • FileReader.readAsBinaryString(): starts reading the specifiedBlobThe content of. Once that’s done,resultProperty will contain the raw binary data for the file being read.
  • FileReader.readAsDataURL(): starts reading the specifiedBlobThe content of. Once that’s done,resultProperty will contain onedata: URLFormat to represent the contents of the file being read.
  • FileReader.readAsText(): starts reading the specifiedBlobThe content of. Once that’s done,resultProperty will contain a string representing the contents of the file being read.

The above document is very clear, but you may not have looked at each item, no matter, we have an example 🙈

Specific application scenarios are as follows:

onDrop(files) {
  files.forEach(file => {
    const reader = new FileReader();
    reader.onload = () => {
      console.log('Jartto files logs: ', file);
      const fileAsBinaryString = reader.result;
      // Todo...
    };
    reader.onabort = () => console.log('file reading was aborted');
    reader.onerror = () => console.log('file reading has failed');
    reader.readAsBinaryString(file);
  });
}Copy the code

onload

Base64 format

We sometimes see code like this on web pages:

data:image/png; base64,iVBORw0KGgoAAAANSUhEUgAAAb4AAABYCAYAAACK55LCAAAgAElEQVR4Xuy9aXNc2ZEleN4e+wIgsO8ACXAnk8mUUqoqldQ9Yz3W/an/wsxvnA/TM 2NWizKVmczkTgIg9h0IxL6+fez4DbCo7JQqpZLZfGBARjEJBOK95/de9+PHj3toO//7f40x/BpaYGiBoQWGFhha4BOxgDYMfJ/ISg8fc2iBoQWGFhhaQCwwD HzDjTC0wNACQwsMLfBJWWAY ...Copy the code

This is base64 Data, which represents the Data of an image. The technical term is Data URI Scheme.

Data URI scheme

Currently, the Data URI scheme supports the following types:

Data :, text data data:text/plain, text data data:text/ HTML,HTML code data:text/ HTML; Base64,base64 encoded HTML code data:text/ CSS,CSS code data:text/ CSS; Base64, base64 encoding of CSS code data: text/javascript, javascript code data: text/javascript. Base64,base64 encoded Javascript code data:image/ GIF; Base64,base64 encoded GIF image data Data :image/ PNG; Base64, Base64 encoded PNG image data data:image/ JPEG; Base64, Base64 encoded JPEG image data data:image/ X-icon; Base64, Base64 encoded icon picture dataCopy the code

Base64 encoding is called Base64 because it uses 64 characters to encode arbitrary data. Base64 encoding is essentially a scheme for converting binary data into text data. For non-binary data, we convert it to binary form, then compute its decimal value for every 6 consecutive bits (2 ^ 6 = 64), find the corresponding character in the index table above based on that value, and finally get a text string.

For more information, please refer to Base64 encoding principles and Applications

Blob format

A Blob (binary large object) is a container for storing binary files.

A Blob is a large file. A Blob is typically an image or a sound file that, due to their size, must be processed in special ways (e.g. uploaded, downloaded, or stored in a database).

Here is a Blob object THAT I converted:

Blob {name: "image example: jartto. PNG ", preview:" Blob :file:///f3823a2a-2908-44cb-81e2-c19d98abc5d1", size: 47396, type: "image/png", }Copy the code

preview

Base64 to Blob

When we get a base64 image code and you think it’s not elegant, or for any other reason, you might want to convert it to Blob format, here’s the code:

base64ToBlob(b64data, contentType, sliceSize) { sliceSize || (sliceSize = 512); Return new Promise((resolve, reject) => {let byteCharacters = atob(b64data); let byteArrays = []; for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) { let slice = byteCharacters.slice(offset, offset + sliceSize); let byteNumbers = []; for (let i = 0; i < slice.length; i++) { byteNumbers.push(slice.charCodeAt(i)); } // A typed array of 8-bit unsigned integer values. The content will be initialized to 0. // If the requested number of bytes cannot be allocated, an exception is thrown. byteArrays.push(new Uint8Array(byteNumbers)); } resolve(new Blob(byteArrays, { type: contentType })) }) }Copy the code

Call method:

// dataUri is your base64 image stream let blob = await this.base64ToBlob(datauri.split (',')[1], 'image/ PNG ');Copy the code

After processing, we get a Blob object, but it might look like this:

Blob {
  size: 47396,
  type: "image/png",
}Copy the code

That’s it. What if my plan to preview was ruined? Don’t worry, let’s add:

Object.assign(blob,{// jartto: preview: url.createObjecturl (blob), name: 'imageexample: ${index}.png'});Copy the code

window.btoa()
atob()

We won’t go into details about ATOB and Uint8Array here, you can check out the documentation:

  • window.atob
  • Uint8Array

Blob to Base64

This is another scenario, probably when you use a third-party plugin, such as drag-and-drop uploads, that automatically returns Blob objects to you, but unfortunately you find yourself using a third-party service interface that only receives Base64 data.

Don’t be afraid, we also have a solution, as follows:

blobToBase64(blob) { return new Promise((resolve, reject) => { const fileReader = new FileReader(); fileReader.onload = (e) => { resolve(e.target.result); }; fileReader.readAsDataURL(blob); Filereader. onerror = () => {reject(new Error(' file stream Error ')); }; }); }Copy the code

Call method:

const allBase64 = await this.blobToBase64(blobObj);Copy the code

I should add that the above scene is a real one I have encountered, and life is full of surprises.

8. Transfer URL to base64

Ok, more interesting things come, I have raised the requirement, just give you the URL of the image (local or online address), can you encode the image into a stream? The answer is yes, here we have to call out canvas:

The idea is very simple: draw canvas according to the data of picture object and use it to represent picture stream equivalently.


getDataUri(url) { return new Promise((resolve, reject) => { /* eslint-disable */ let image = new Image(); image.onload = function() { let canvas = document.createElement('canvas'); canvas.width = this.naturalWidth; canvas.height = this.naturalHeight; canvas.getContext('2d').drawImage(this, 0, 0); // Data URI resolve(canvas.toDataURL('image/png')); }; image.src = url; // console.log(image.src); Image.onerror = () => {reject(new Error(' image stream Error ')); }; }); }Copy the code

You can call it like this:

let dataUri = await this.getDataUri(`image/test/jartto.png`);Copy the code

Common questions and supplementary notes

1.Failed to execute ‘readAsDataURL’ on ‘FileReader’: parameter 1 is not of type ‘Blob’. When this happens, check that your Blob object is formatted correctly and missing any necessary items.

2. Many third-party applications need to remove base64 headers:

base64.replace(/^data:image\/(jpeg|png|gif); base64,/,'')Copy the code

3. After FileReader reads the file, remember to place it in the onload function.

Canvas. GetContext (‘2d’). DrawImage (this, 0, 0); Make sure you pay attention to the this reference, otherwise an exception may occur.

5. Base64 to Blob, please remember:

Object.assign(blob,{// jartto: preview: url.createObjecturl (blob), name: 'imageexample: ${index}.png'});Copy the code

Ten,

Is an image spinning around a bit confusing? Trust me, if you read the article carefully, you will be able to process the image data much more smoothly.

I always like to write articles in this way: after the project, write down the questions, and then understand them point by point. Knowledge is like a branch of a tree. You keep learning and reflecting, it keeps spreading and dividing, and over time it will form a web.

So, study hard, let yourself grow into a towering tree, full of vitality, block the sun.

11. Reference resources

Blob MDN FileReader Convert Image to Data URI HTML base64 IMG Image display