Reputation: 1367
I wanted to convert an image to blob url I currently can do it if user uploads the image through an input tag but what I want is what if I had a src url for the image how can I get that image then convert that image to blob. Thanks in advance.
EDIT: Someone suggested a similar question, I tried to apply a similar method but I am not getting a blob url back I have updated my code to show the following.
Suggested SO URL: convert image into blob using javascript
//this works for when image is uploaded through an input tag
const image_input = document.querySelector("#image_input");
image_input.addEventListener("change", function() {
const reader = new FileReader();
reader.addEventListener("load", () => {
const uploaded_image = reader.result;
console.log(uploaded_image)
});
reader.readAsDataURL(this.files[0]);
});
//Suggested Method
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)
}
});
}
//I want to get the image throught a src link the convert that to blob url
//somthing like this
//convert src to blob
//console.log(blobUrl)
const src = '../img/myImage.jpg'
loadXHR(src).then(function(blob) {
//I currently only get back an object with size and and type not the blob url it self
console.log(blob)
});
<input type="file" title="" id="image_input">
Upvotes: 4
Views: 30453
Reputation: 13195
If you just want an URL for a blob, and don't need the actual Base64-encoded string, URL.createObjectURL()
may be simpler than the FileReader
-magic.
Here this approach is used for providing src
for multiple images, while ensuring that only a single HTTP request will be made (even if the browser cache is disabled).
fetch("https://i.imgur.com/gDJ1JhL.jpeg")
.then(response => response.blob())
.then(blob => {
const url = URL.createObjectURL(blob);
for (const img of document.querySelectorAll("img"))
img.src = url;
});
<img style="width:30%"><img style="width:20%"><img style="width:10%">
(Image credit: dimitriartist, linked from Imgur, https://i.sstatic.net/sEv3O.jpg)
EDIT:
As @REJH suggests, the really pedant way is to free the object URL after use (automatic clean up will happen only when the document gets unloaded). What complicates things here is that this means waiting for all 3 image tags to complete "loading", and only then can the URL be gone safely. One option is to simply count the loaded events, another one is to promisify them, and use Promise.allSettled()
to wait for all of them succeeding/failing. I try this latter approach here:
fetch("https://i.imgur.com/gDJ1JhL.jpeg")
.then(response => response.blob())
.then(blob => {
const url = URL.createObjectURL(blob);
const imgs = Array.from(document.querySelectorAll("img"));
Promise.allSettled(imgs.map(img => {
img.src = url;
return new Promise((resolve, reject) => {
img.onload = () => {
console.log("One loaded");
resolve();
};
img.onerror = () => {
console.log("One failed");
reject();
};
});
})).then(e => {
console.log("All settled");
URL.revokeObjectURL(url);
});
});
<img style="width:30%"><img style="width:20%"><img style="width:10%">
Upvotes: 5
Reputation: 144
Try this way.
const src = '../img/myImage.jpg'
loadXHR(src).then(function(blob) {
// Here blob is object, you need to convert it to base64 by using FileReader
const reader = new FileReader();
reader.addEventListener("load", () => {
const uploaded_image = reader.result;
console.log(uploaded_image);
});
reader.readAsDataURL(blob);
});
Upvotes: 1