At first I thought it should be as easy as:
const img = document.createElement('img');
img.onload = () => { ... }
img.onerror = () => { ... }
img.src = url;
But then it turned out I need to draw it on a canvas, then toBlob(). And don't forget to add CORS and crossorigin="anonymous" to the img tag. Isn't it a bit too involved? Is there a better way?
To show you the final solution (you need CORS headers):
function getFileFromURL(url) {
return new Promise((resolve, reject) => {
const fileName = url.split('/').pop();
const img = document.createElement('img');
img.setAttribute('crossorigin', 'anonymous');
img.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
canvas.toBlob(blob => {
resolve(new File([blob], fileName));
});
};
img.onerror = () => {
reject('something went wrong');
};
img.src = url;
})
}
The solution suggested by CBroe is arguably better:
function getFileFromURL(url) {
const fileName = url.split('/').pop();
return fetch(url)
.then(response => {
return new File([response.data], fileName);
});
}
Make sure you add CORS headers to the request(s).
Using an Image File, I am getting the url of an image, that needs be to send to a webservice. From there the image has to be saved locally on my system.
The code I am using:
var imagepath = $("#imageid").val();// from this getting the path of the selected image
that var st = imagepath.replace(data:image/png or jpg; base64"/"");
How to convert the image url to BASE64?
HTML
<img id="imageid" src="https://www.google.de/images/srpr/logo11w.png">
JavaScript
function getBase64Image(img) {
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/png");
return dataURL.replace(/^data:image\/?[A-z]*;base64,/);
}
var base64 = getBase64Image(document.getElementById("imageid"));
Special thanks to #Md. Hasan Mahmud for providing an improved regex that works with any image mime type in my comments!
This method requires the canvas element, which is perfectly supported.
The MDN reference of HTMLCanvasElement.toDataURL().
And the official W3C documentation.
View this answer: https://stackoverflow.com/a/20285053/5065874 by #HaNdTriX
Basically, he implemented this function:
function toDataUrl(url, callback) {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
var reader = new FileReader();
reader.onloadend = function() {
callback(reader.result);
}
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.send();
}
And in your case, you can use it like this:
toDataUrl(imagepath, function(myBase64) {
console.log(myBase64); // myBase64 is the base64 string
});
In todays JavaScript, this will work as well..
const getBase64FromUrl = async (url) => {
const data = await fetch(url);
const blob = await data.blob();
return new Promise((resolve) => {
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = () => {
const base64data = reader.result;
resolve(base64data);
}
});
}
getBase64FromUrl('https://lh3.googleusercontent.com/i7cTyGnCwLIJhT1t2YpLW-zHt8ZKalgQiqfrYnZQl975-ygD_0mOXaYZMzekfKW_ydHRutDbNzeqpWoLkFR4Yx2Z2bgNj2XskKJrfw8').then(console.log)
This is your html-
<img id="imageid" src="">
<canvas id="imgCanvas" />
Javascript should be-
var can = document.getElementById("imgCanvas");
var img = document.getElementById("imageid");
var ctx = can.getContext("2d");
ctx.drawImage(img, 10, 10);
var encodedBase = can.toDataURL();
'encodedBase' Contains Base64 Encoding of Image.
You Can Used This :
function ViewImage(){
function getBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
}
var file = document.querySelector('input[type="file"]').files[0];
getBase64(file).then(data =>$("#ImageBase46").val(data));
}
Add To Your Input onchange=ViewImage();
I try using the top answer, but it occur Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
I found this is because of cross domain problems, the solution is
function convert(oldImag, callback) {
var img = new Image();
img.onload = function(){
callback(img)
}
img.setAttribute('crossorigin', 'anonymous');
img.src = oldImag.src;
}
function getBase64Image(img,callback) {
convert(img, function(newImg){
var canvas = document.createElement("canvas");
canvas.width = newImg.width;
canvas.height = newImg.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(newImg, 0, 0);
var base64=canvas.toDataURL("image/png");
callback(base64)
})
}
getBase64Image(document.getElementById("imageid"),function(base64){
// base64 in here.
console.log(base64)
});
<input id="inputFileToLoad" type="file" onchange="encodeImageFileAsURL();" />
<div id="imgTest"></div>
<script type='text/javascript'>
function encodeImageFileAsURL() {
var filesSelected = document.getElementById("inputFileToLoad").files;
if (filesSelected.length > 0) {
var fileToLoad = filesSelected[0];
var fileReader = new FileReader();
fileReader.onload = function(fileLoadedEvent) {
var srcData = fileLoadedEvent.target.result; // <--- data: base64
var newImage = document.createElement('img');
newImage.src = srcData;
document.getElementById("imgTest").innerHTML = newImage.outerHTML;
alert("Converted Base64 version is " + document.getElementById("imgTest").innerHTML);
console.log("Converted Base64 version is " + document.getElementById("imgTest").innerHTML);
}
fileReader.readAsDataURL(fileToLoad);
}
}
</script>
let baseImage = new Image;
baseImage.setAttribute('crossOrigin', 'anonymous');
baseImage.src = your image url
var canvas = document.createElement("canvas");
canvas.width = baseImage.width;
canvas.height = baseImage.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(baseImage, 0, 0);
var dataURL = canvas.toDataURL("image/png");
Additional information about "CORS enabled images": MDN Documentation
imageToBase64 = (URL) => {
let image;
image = new Image();
image.crossOrigin = 'Anonymous';
image.addEventListener('load', function() {
let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');
canvas.width = image.width;
canvas.height = image.height;
context.drawImage(image, 0, 0);
try {
localStorage.setItem('saved-image-example', canvas.toDataURL('image/png'));
} catch (err) {
console.error(err)
}
});
image.src = URL;
};
imageToBase64('image URL')
Here's the Typescript version of Abubakar Ahmad's answer
function imageTo64(
url: string,
callback: (path64: string | ArrayBuffer) => void
): void {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.send();
xhr.onload = (): void => {
const reader = new FileReader();
reader.readAsDataURL(xhr.response);
reader.onloadend = (): void => callback(reader.result);
}
}
Just wanted to chime in and post how I did it. This is basically #Haialaluf's approach but a bit shorter:
const imageUrlToBase64 = async (url) => {
const data = await fetch(url)
const blob = await data.blob();
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = () => {
const base64data = reader.result;
return base64data
}
}
I'm having issues reading sizes with file reader. Have tried various browsers and files, width always comes back as 0.
var fileReader = new FileReader();
var img = new Image();
fileReader.onload = function(event) {
img.src = event.target.result;
console.log(img.width);
};
fileReader.onerror = function() {
//handle error
};
fileReader.readAsDataURL(file);
The file var is looped out from the following on a drag and drop event:
e.originalEvent.dataTransfer.files
I think you have an error while assigning binary data to Image.
Assigning image:
fileReader.onload = function(e) {
var img = new Image();
img.src = fileReader.result;
}
Demo:
document.getElementById('img').addEventListener('change', function(e) {
var file = this.files[0];
var fileReader = new FileReader();
var img = new Image();
fileReader.onload = function(event) {
img.src = fileReader.result;
img.onload = function() {
console.log(img.width);
}
document.getElementById('result').appendChild(img);
};
fileReader.readAsDataURL(file);
})
<input id="img" type="file">
<div id="result"></div>
see codepen demo or jsfiddle
maybe your image object is not loaded try this :
img.onload = function () {console.log(img.width)}
I have a php file "linkToThePhpFileHere.php". It creates a QR Code and returns something like that:
https://i.stack.imgur.com/y7zHA.png
That's how I display the code:
<div style="background-image: url(linkToThePhpFileHere.php);"></div>
But I want to store the content of "linkToThePhpFileHere.php" in an array in the local storage of the browser and I think, it's not a good idea to save the binary code there?
Is it possible to use Javascript/Jquery to load and convert the cotent of my file. It should look like this: https://i.stack.imgur.com/soYPr.png and be saved in a var:
var str = convertToSth($.get("linkToThePhpFileHere.php"));
var str = convertToSth($.get("linkToThePhpFileHere.php"));//this should be in base64
localStorage.setItem("imgData", str );
function getBase64Image(img) {
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/png");
return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}
function getImage(imageUrl, callback) {
var img = document.createElement("img");
img.setAttribute('crossOrigin', 'anonymous');
img.src = imageUrl;
img.onload = function() {
var str = getBase64Image(img);
if (typeof callback == "function") callback(str);
}
}
getImage('https://upload.wikimedia.org/wikipedia/commons/f/f9/Phoenicopterus_ruber_in_S%C3%A3o_Paulo_Zoo.jpg',function(imgData){
localStorage.setItem("imgData1", str );
})
getImage('linkToThePhpFileHere.php',function(imgData){
localStorage.setItem("imgData1", str );
})
You can store data URI representation of image in localStorage
window.onload = () => {
if (localStorage.getItem("image") === null) {
fetch("linkToThePhpFileHere.php")
.then(response => reponse.blob())
.then(blob => {
const reader = new FileReader;
reader.onload = () {
localStorage.setItem("image", reader.result);
document.querySelector("div")
.style.backgroundImage = "url(" + reader.result + ");";
}
reader.readAsDataURL(blob)
})
} else {
document.querySelector("div")
.style.backgroundImage = "url(" + localStorage.getImage("image") + ")";
}
}
I'm switching an implementation of a cross-site request for an image converted to base 64 from Canvas to XMLHttpRequest and FileReader, so that it can be used inside of web workers. And I want to know if there's a way to get the image width and height from the get-go.
The new function
var convertFileToDataURLviaFileReader = function (url, callback) {
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function () {
var reader = new FileReader();
reader.onloadend = function () {
callback(reader.result);
}
reader.readAsDataURL(xhr.response);
};
// Our workaround for the Amazon CORS issue
// Replace HTTPs URL with HTTP
xhr.open('GET', url.replace(/^https:\/\//i, 'http://'));
xhr.send();
}
Our old Function
var convertImgToDataURLviaCanvas = function(url, callback, outputFormat) {
var img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = function () {
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var dataURL;
canvas.height = this.height;
canvas.width = this.width;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL(outputFormat);
var allInfo = {
data: dataURL,
width: this.width,
height: this.height
}
// Add height and width to callback
callback(allInfo);
canvas = null;
};
// Our workaround for the Amazon CORS issue
// Replace HTTPs URL with HTTP
img.src = url.replace(/^https:\/\//i, 'http://');
}
In the old function I can just get the height and width with canvas, and I do so inside of the var allInfo. Is there an equivalent for FileReader or some way to get the width and height inside of the new function?
To clarify, I am switching to the XMLHttpRequest because Web Workers don't have access to the DOM, so Canvas can't be used.
Have a look at this code, it's just a quick rework of this example https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL
Is your reader.result a string in base 64 encoding ?
<form>
<input type="file" onchange="previewFile()"><br>
<img src="" alt="Image preview..."><!-- height and width are not set -->
</form>
<script>
var previewFile = () => {
"use strict";
let file = document.querySelector("input[type=file]").files[0];
let fileReader = new FileReader();
let preview = document.querySelector("img")
fileReader.addEventListener("load", () => {
preview.src = fileReader.result;
// here preview.height and preview.width are accessible
// if height and width are not set in the img element in the html
});
if (file) {
fileReader.readAsDataURL(file);
}
};
</script>