admin管理员组

文章数量:1317898

I have a requirement to convert an input image (blob) to base64 image. Im aware the size will increase by approx 1.37.

However i have noticed when using the firereader.readAsDataUrl the size of the image is extremely large when pared to the built in base64 mand line tool you have on macOS.

Steps to reproduce:

  1. Download this free sample image .php?i=685897 make sure to click the Download button (Downlaod Original 8000x600). Do not use right click save as because the image will be pressed

  2. Use the jsfiddle to pick the above downloaded image and check the console log for the size of the base 64. / you can see the size is 11.2mb.

  3. Now if your on mac use the base64 mand line tool to convert the above downloaded image to base64 and check the file size there. You will see the base64 size here is. 5.9mb. base64 -w 0 downloaded_image.jpg > downloaded_image.base64

This is the function i am using in my code to convert an input file image to base64.

async convertToBase64(file) {

  if (file === undefined) {
    throw new Error("File could not be found");
  }

  const fileReader = new FileReader();

  return new Promise((resolve, reject) => {
    fileReader.readAsDataURL(file);

    fileReader.onerror = (error) => {
      reject("Input: File could not be read:" + error);
    };

    fileReader.onloadend = () => {
      resolve(fileReader.result);
    };
  });

}

Why does the filereader.readAsDataURL make the image base64 output extremely large.

How can i make this more efficient?

I have a requirement to convert an input image (blob) to base64 image. Im aware the size will increase by approx 1.37.

However i have noticed when using the firereader.readAsDataUrl the size of the image is extremely large when pared to the built in base64 mand line tool you have on macOS.

https://developer.mozilla/en-US/docs/Web/API/FileReader/readAsDataURL

Steps to reproduce:

  1. Download this free sample image https://wall.alphacoders./big.php?i=685897 make sure to click the Download button (Downlaod Original 8000x600). Do not use right click save as because the image will be pressed

  2. Use the jsfiddle to pick the above downloaded image and check the console log for the size of the base 64. https://jsfiddle/b7nkw8j9/ you can see the size is 11.2mb.

  3. Now if your on mac use the base64 mand line tool to convert the above downloaded image to base64 and check the file size there. You will see the base64 size here is. 5.9mb. base64 -w 0 downloaded_image.jpg > downloaded_image.base64

This is the function i am using in my code to convert an input file image to base64.

async convertToBase64(file) {

  if (file === undefined) {
    throw new Error("File could not be found");
  }

  const fileReader = new FileReader();

  return new Promise((resolve, reject) => {
    fileReader.readAsDataURL(file);

    fileReader.onerror = (error) => {
      reject("Input: File could not be read:" + error);
    };

    fileReader.onloadend = () => {
      resolve(fileReader.result);
    };
  });

}

Why does the filereader.readAsDataURL make the image base64 output extremely large.

How can i make this more efficient?

Share Improve this question edited Jul 4, 2019 at 15:27 Kay asked Jul 4, 2019 at 15:01 KayKay 19.7k71 gold badges184 silver badges301 bronze badges 8
  • @Kaiido sorry i dont understand what you mean? – Kay Commented Jul 4, 2019 at 15:12
  • I mean I don't have 11.2MB but a string of length 5,882,455 containing only ASCII safe characters (e.g a 5.9MB utf-8 text file) – Kaiido Commented Jul 4, 2019 at 15:23
  • how? i can see in the console window 11.2mb what have you changed? – Kay Commented Jul 4, 2019 at 15:24
  • How do you see 11.2mb? The fiddle you linked to only outputs the string. – Kaiido Commented Jul 4, 2019 at 15:26
  • @Kaiido please see the screenshot i sent ive displayed in my question it shows 11.2mb in console window. – Kay Commented Jul 4, 2019 at 15:27
 |  Show 3 more ments

1 Answer 1

Reset to default 7

I have 5,882,455 bytes for the FileReader vs 5,882,433 bytes for base64 output, if you add the 22 bytes from data:image/png;base64,, we're not too far.

However to the question How can i make this more efficient?, just don't use a data URL here. Whatever you've been told you need it too, it was a lie (I'm 99% percent sure).

Instead you should always prefer to work with the Blob directly.

To display it, use a blob URL:

inp.onchange = e => {
  img.src = URL.createObjectURL(inp.files[0]);
};
<input type="file" id="inp">
<img id="img" src="" height="200" alt="Image preview..." accept="image/*">

To send it to your server, send the Blob directly, either through a FormData or, directly from xhr.send() or as the body of a fetch request.

The only case can think of where you would need a data URL version of a binary file on the front end is to generate a standalone document which would need to embed that binary file. For all other use cases I met in my career, Blob where far better suited.


For the message that gets printed in the Chrome's tooltip, that's the size of the USVString that the browser has to hold in memory. It's twice the size of the file you have on disk, because USVStrings are encoded in UTF-16, even though this string holds only ASCII characters.
However, to be sent to your server, or to be saved as a text file, it will generally be reencoded in an 8 bit encoding, and retrieve it's normal size.

So don't take this tooltip as a mean to tell you how big your data is, it's only the size it does take in the browser's allocated memory, but outside, it won't be the same at all.

If you wanna check the size of binary data generated here is a better fiddle, which will convert USVStrings to UTF-8 and keep binary as binary (e.g if you pass an ArrayBuffer to it):

function previewFile() {
  var preview = document.querySelector('img');
  var file    = document.querySelector('input[type=file]').files[0];
  var reader  = new FileReader();

  reader.addEventListener("load", function () {
    console.log(new Blob([reader.result]).size);
    preview.src = reader.result;
  }, false);

  if (file) {
    reader.readAsDataURL(file);
  }
}
<!-- Learn about this code on MDN: https://developer.mozilla/en-US/docs/Web/API/FileReader/readAsDataURL -->

<input type="file" onchange="previewFile()"><br>
<img src="" height="200" alt="Image preview...">

本文标签: javascriptFileReader readAsDataURL creating large base64 imagesStack Overflow