49

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.

2
  • "I use promise to download a image" then you should probably get a base64 version instead of URL if you're downloading, right? Commented Feb 27, 2017 at 6:49
  • 5
    var blob = new Blob([dataURI], {type : 'image/svg+xml'}); Commented Apr 27, 2018 at 1:57

1 Answer 1

79

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:

const img = new Image;
const c = document.createElement("canvas");
const 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";
Sign up to request clarification or add additional context in comments.

3 Comments

@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 devdocs.io/javascript/operators/this
I wonder in the canvas method, what is supposed to go in the variable for img.crossOrigin = ""?
the blob returns same image everytime. How can i correct this?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.