118

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?

ˈvɔlə
  • 9,204
  • 10
  • 63
  • 89
im_chethi
  • 1,183
  • 2
  • 8
  • 7
  • possible duplicate of [How can you encode a string to Base64 in JavaScript?](http://stackoverflow.com/questions/246801/how-can-you-encode-a-string-to-base64-in-javascript) – S.C. Mar 04 '14 at 13:10
  • If you're just trying to encode the url and not the image data, you might find your answer here: http://stackoverflow.com/questions/246801/how-can-you-encode-a-string-to-base64-in-javascript – S.C. Mar 04 '14 at 13:11

12 Answers12

164

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.

ˈvɔlə
  • 9,204
  • 10
  • 63
  • 89
  • 43
    This does not work when you create and add the `` in JS, I believe. Because I got `Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.`. – Rubinous Jan 07 '16 at 11:20
  • 11
    @Rubinous - Please refer to [this question](http://stackoverflow.com/questions/20424279/canvas-todataurl-securityerror). I don't think your problem/exception has something to do with my code. Otherwise, feel free to prove me wrong. – ˈvɔlə Jan 07 '16 at 13:45
  • 3
    This is the correct answer to OP's question. For my sake, I wanted to use the actual results of `toDataURL` in a CSS `background-image`. So, I **do need** all the preceding `data:image/png;base64,` stuff, so I just returned dataURL's value directly (I didn't need the RegEx replace). Thanks! – Nate Anderson Jan 02 '17 at 23:07
  • 1
    The conversion part `var dataURL = canvas.toDataURL("image/png"); return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");` works great on Angular too. – vss May 25 '18 at 06:15
  • 5
    You need to use img.naturalWidth and img.naturalHeight to handle scaled-down images – Mehmet K Jul 27 '18 at 11:13
  • 2
    i like to use `return dataURL.split(',')[1];` instead of your version, and yep! height and width were needed i found out the hard way :p – some_groceries Jan 29 '19 at 14:06
  • 1
    I have src="/something.svg" like this how do i convert this. – Himanshu Rawat Feb 03 '22 at 12:17
  • 1
    The best conversion would be: const dataURL = canvas.toDataURL("image/png"); dataURL.replace(/^data:image\/?[A-z]*;base64,/); work for any type of image extension(png,jpeg,jpg etc) – Md. Hasan Mahmud Dec 09 '22 at 20:09
82

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
});
Community
  • 1
  • 1
Abubakar Ahmad
  • 2,567
  • 1
  • 18
  • 16
57

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)
Hai Alaluf
  • 757
  • 7
  • 15
2

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.

Mandeep Singh
  • 983
  • 8
  • 9
2

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)
});
Weijan Chen
  • 67
  • 1
  • 3
  • By this https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image your code will not work without server side change ... adding header Access-Control-Allow-Origin for image. So if we wish to convert image from 3rd party domain your code will not work. In case facebook or google user image from OAuth2 login is this code working because of both return header `Access-Control-Allow-Origin: *` :) Thanks. – mikep Mar 31 '23 at 12:33
1

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();

0
<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>
0
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

ˈvɔlə
  • 9,204
  • 10
  • 63
  • 89
Edhar Dowbak
  • 2,648
  • 1
  • 10
  • 13
  • be advice, you'ld wrap the conversion within an event handler connecting to the loaded event since the image might not be loaded when trying to convert; https://stackoverflow.com/a/7442874/1098814 – genuinefafa May 29 '18 at 23:52
  • I get error https://stackoverflow.com/questions/54108669/typescript-uncaught-domexception-failed-to-execute-todataurl-on-htmlcanvas?noredirect=1#comment95051919_54108669 – Wrong Jan 09 '19 at 12:15
0
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')
ˈvɔlə
  • 9,204
  • 10
  • 63
  • 89
Asif vora
  • 3,163
  • 3
  • 15
  • 31
0

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
    }
}
Artur Müller Romanov
  • 4,417
  • 10
  • 73
  • 132
0

This one uses canvas.ToDataURL(...)

function getBase64Image(img) {
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");
  ctx.drawImage(img, 0, 0);
  const dataURL = canvas.toDataURL("image/png");
  return dataURL;
}

This one works in more cases because it avoids canvas by re-fetching the img.src

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);
    }
  });
}

As a bonus, this one uses both functions before to read all images in the page and uses the first function if it works, otherwise it uses the second one, and returns a markdown image embedding of the image with its alt text as the title and the base64 as the source.

const images = document.getElementsByTagName('img');
[...images].forEach(async img => {
  let base64;
  try {
    base64 = getBase64Image(img);      
  } catch (error) {
    base64 = await getBase64FromUrl(img.src);
  };
  const markdown = `![${img.alt}](${base64})`;
  console.log(markdown, img);
})
Madacol
  • 3,611
  • 34
  • 33
-2

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);
  }
}
Sergi
  • 743
  • 1
  • 9
  • 17