45

I use promise to download an image and get the image data like:

promise.downloadFile().then(function(image){                
    //do something
});

I have got the image, which is like:

<img name="imageXXX" crossorigin="" src="/images/grass.jpg">

how can I convert the image into a blob? (Similar to below snippet)

var blob = new Blob([????], "image/jpg");

how can I get/access the [????] from the image ? I don't know how to get the image context.

Jonathan Lin
  • 19,922
  • 7
  • 69
  • 65
caxieyou110
  • 517
  • 1
  • 4
  • 8

1 Answers1

72

You can do this in two ways:

  • Load the image source using XMLHttpRequest() or fetch() instead of an image element
  • Convert image element via a canvas element. This will recompress the image causing some quality loss. There is also the "risk" of color/gamma changes depending of the image contains ICC/gamma information and/or the browser support this information. Ie. the image won't be exact the same as the original - if you just want the original image to be represented as a blob, use method 1.

For method one and since you're already using promises, you can do:

function loadXHR(url) {

    return new Promise(function(resolve, reject) {
        try {
            var xhr = new XMLHttpRequest();
            xhr.open("GET", url);
            xhr.responseType = "blob";
            xhr.onerror = function() {reject("Network error.")};
            xhr.onload = function() {
                if (xhr.status === 200) {resolve(xhr.response)}
                else {reject("Loading error:" + xhr.statusText)}
            };
            xhr.send();
        }
        catch(err) {reject(err.message)}
    });
}

Then get the image as Blob using it like this:

loadXHR("url-to-image").then(function(blob) {
  // here the image is a blob
});

or use fetch() in browsers which support this:

fetch("url-to-image")
  .then(function(response) {
    return response.blob()
  })
  .then(function(blob) {
    // here the image is a blob
  });

The other method will require a canvas:

var img = new Image;
var c = document.createElement("canvas");
var ctx = c.getContext("2d");

img.onload = function() {
  c.width = this.naturalWidth;     // update canvas size to match image
  c.height = this.naturalHeight;
  ctx.drawImage(this, 0, 0);       // draw in image
  c.toBlob(function(blob) {        // get content as JPEG blob
    // here the image is a blob
  }, "image/jpeg", 0.75);
};
img.crossOrigin = "";              // if from different origin
img.src = "url-to-image";
  • @Martian2049 `this` context inside the handler (when using function()) is the image itself. This allow you to share then handler between several image instances and always be sure you're dealing with the correct image. For more info, see https://devdocs.io/javascript/operators/this –  Jul 14 '18 at 07:23
  • I wonder in the canvas method, what is supposed to go in the variable for img.crossOrigin = ""? – netskink Jan 30 '22 at 16:45
  • the blob returns same image everytime. How can i correct this? – Alia Anis Sep 08 '22 at 06:51