coderslay
coderslay

Reputation: 14370

How can I convert an image into Base64 string using JavaScript?

I need to convert my image to a Base64 string so that I can send my image to a server.

Is there any JavaScript file for this? Else, how can I convert it?

Upvotes: 759

Views: 1357528

Answers (20)

Jonathan Applebaum
Jonathan Applebaum

Reputation: 5986

I found that the safest and reliable way to do it is to use FileReader().

Demo: Image to Base64

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <input id="myinput" type="file" onchange="encode();" />
    <div id="dummy">
    </div>
    <div>
      <textarea style="width:100%;height:500px;" id="txt">
      </textarea>
    </div>
    <script>
      function encode() {
        var selectedfile = document.getElementById("myinput").files;
        if (selectedfile.length > 0) {
          var imageFile = selectedfile[0];
          var fileReader = new FileReader();
          fileReader.onload = function(fileLoadedEvent) {
            var srcData = fileLoadedEvent.target.result;
            var newImage = document.createElement('img');
            newImage.src = srcData;
            document.getElementById("dummy").innerHTML = newImage.outerHTML;
            document.getElementById("txt").value = document.getElementById("dummy").innerHTML;
          }
          fileReader.readAsDataURL(imageFile);
        }
      }
    </script>
  </body>
</html>

UPDATE: the same code with comments for @AnniekJ request:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <input id="myinput" type="file" onchange="encode();" />
    <div id="dummy">
    </div>
    <div>
      <textarea style="width:100%;height:500px;" id="txt">
      </textarea>
    </div>
    <script>
      function encode() {
        // Get the file objects that was selected by the user from myinput - a file picker control
        var selectedfile = document.getElementById("myinput").files;
        // Check that the user actually selected file/s from the "file picker" control
        // Note - selectedfile is an array, hence we check it`s length, when length of the array
        // is bigger than 0 than it means the array containes file objects
        if (selectedfile.length > 0) {
          // Set the first file object inside the array to this variable
          // Note: if multiple files are selected we can iterate over all of the selectedfile array  using a for loop - BUT in order to not make this example complicated we only take the first file object that was selected
          var imageFile = selectedfile[0];
          // Set a filereader object to asynchronously read the contents of files (or raw data buffers) stored on the            user's computer, using File or Blob objects to specify the file or data to read. 
          var fileReader = new FileReader();
          // We declare an event of the fileReader class (onload event) and we register an anonimous function that will be executed when the event is raised. it is "trick" we preapare in order for the onload event to be raised after the last line of this code will be executed (fileReader.readAsDataURL(imageFile);) - please read about events in javascript if you are not familiar with "Events" 
          fileReader.onload = function(fileLoadedEvent) {
            // AT THIS STAGE THE EVENT WAS RAISED
            // Here we are getting the file contents - basiccaly the base64 mapping
            var srcData = fileLoadedEvent.target.result;
            // We create an image html element dinamically in order to display the image
            var newImage = document.createElement('img');
            // We set the source of the image we created
            newImage.src = srcData;
            // ANOTHER TRICK TO EXTRACT THE BASE64 STRING
            // We set the outer html of the new image to the div element
            document.getElementById("dummy").innerHTML = newImage.outerHTML;
            // Then we take the inner html of the div and we have the base64 string
            document.getElementById("txt").value = document.getElementById("dummy").innerHTML;
          }
          // This line will raise the fileReader.onload event - note we are passing the file object here as an argument to the function of the event  
          fileReader.readAsDataURL(imageFile);
        }
      }
    </script>
  </body>
</html>

Upvotes: 25

mehmet mecek
mehmet mecek

Reputation: 2685

Basically, if your image is

<img id='Img1' src='someurl'>

then you can convert it like

var c = document.createElement('canvas');
var img = document.getElementById('Img1');
c.height = img.naturalHeight;
c.width = img.naturalWidth;
var ctx = c.getContext('2d');

ctx.drawImage(img, 0, 0, c.width, c.height);
var base64String = c.toDataURL();

Upvotes: 53

Jexlah
Jexlah

Reputation: 53

Probably the most straightforward method nowadays to get a base64 string is to use an ArrayBuffer.

In server-side code you can use Buffer:

const arrayBufferToBase64 = (arrayBuffer) =>
  Buffer.from(arrayBuffer).toString("base64");

In client-side code you can use btoa and Uint8Array:

const arrayBufferToBase64 = (arrayBuffer) =>
  btoa(String.fromCodePoint(...new Uint8Array(arrayBuffer)));

Not sure how to get an ArrayBuffer object? Here are some examples:

  // from `fetch`
  const arrayBuffer = await fetch('...').then(res => res.arrayBuffer())
  // from `File | Blob` object
  const arrayBuffer = await fileOrBlob.arrayBuffer()
  // from `axios`
  const arrayBuffer = await axios.request({ responseType: "arraybuffer" }).then({ data } => data)

Upvotes: 4

HaNdTriX
HaNdTriX

Reputation: 29746

There are multiple approaches you can choose from:

1. Approach: FileReader

Load the image as blob via XMLHttpRequest and use the FileReader API (readAsDataURL()) to convert it to a dataURL:

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

toDataURL('https://www.gravatar.com/avatar/d50c83cc0c6523b4d3f6085295c953e0', function(dataUrl) {
  console.log('RESULT:', dataUrl)
})

This code example could also be implemented using the WHATWG fetch API:

const toDataURL = url => fetch(url)
  .then(response => response.blob())
  .then(blob => new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onloadend = () => resolve(reader.result)
    reader.onerror = reject
    reader.readAsDataURL(blob)
  }))


toDataURL('https://www.gravatar.com/avatar/d50c83cc0c6523b4d3f6085295c953e0')
  .then(dataUrl => {
    console.log('RESULT:', dataUrl)
  })

These approaches:

  • have better compression
  • work for other file types as well

Browser Support:

Tip: To convert local files, you can use live-server. Once started on the folder that contains the picture to transform, open the url in browser and using developer console you can convert the image to base 64.


2. Approach: Canvas (for legacy browsers)

Load the image into an Image-Object, paint it to a nontainted canvas and convert the canvas back to a dataURL.

function toDataURL(src, 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.naturalHeight;
    canvas.width = this.naturalWidth;
    ctx.drawImage(this, 0, 0);
    dataURL = canvas.toDataURL(outputFormat);
    callback(dataURL);
  };
  img.src = src;
  if (img.complete || img.complete === undefined) {
    img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
    img.src = src;
  }
}

toDataURL(
  'https://www.gravatar.com/avatar/d50c83cc0c6523b4d3f6085295c953e0',
  function(dataUrl) {
    console.log('RESULT:', dataUrl)
  }
)

In detail

Supported input formats:

image/png, image/jpeg, image/jpg, image/gif, image/bmp, image/tiff, image/x-icon, image/svg+xml, image/webp, image/xxx

Supported output formats:

image/png, image/jpeg, image/webp(chrome)

Browser Support:


3. Approach: Images from the local file system

If you want to convert images from the users file system you need to take a different approach. Use the FileReader API:

function encodeImageFileAsURL(element) {
  var file = element.files[0];
  var reader = new FileReader();
  reader.onloadend = function() {
    console.log('RESULT', reader.result)
  }
  reader.readAsDataURL(file);
}
<input type="file" onchange="encodeImageFileAsURL(this)" />

Upvotes: 1210

MD ALI
MD ALI

Reputation: 65

This is very simple. 1> Just call the function and pass your image. 2> Save the return value and use wherever required.

//call like this
const convertedFile = await imageToBase64(fileObj);
console.log("convertedFile",convertedFile);

//this is the required function

 async function  imageToBase64(image) {
 const reader = new FileReader();
 reader.readAsDataURL(image);
 const data= await new Promise((resolve, reject) => {

   reader.onload = () => resolve(reader.result);

   reader.onerror = error => reject(error);

  });
return data;
}

export default imageToBase64;

Upvotes: 0

Žilvinas Rudžionis
Žilvinas Rudžionis

Reputation: 2346

Assuming that you are doing this in a browser:

With await:

import axios from 'axios'

const response = await axios.get(url, { responseType: 'blob' });
return window.URL.createObjectURL(response.data);

With promise

import axios from 'axios'

const response = await axios.get(url, { responseType: 'blob' })
  .then((response) => {
    const dataUrl = window.URL.createObjectURL(response.data);
    // do something with your url
  });

Upvotes: 2

Vinnie Amir
Vinnie Amir

Reputation: 621

You can also simply extract base-64 only part of the URL by ding this:

var Base64URL = canvas.toDataURL('image/webp')
var Base64 = Base64URL.split(",")[1] //Returns the base64 part

Upvotes: 0

Jakub A Suplicki
Jakub A Suplicki

Reputation: 4801

I ended up using a function that returns a Promise.

const getImg64 = async() => {
  const convertImgToBase64URL = (url) => {
  console.log(url)
    return new Promise((resolve, reject) => {
      const img = new Image();
      img.crossOrigin = 'Anonymous';
      img.onload = () => {
          let canvas = document.createElement('CANVAS')
          const ctx = canvas.getContext('2d')
          canvas.height = img.height;
          canvas.width = img.width;
          ctx.drawImage(img, 0, 0);
          const dataURL = canvas.toDataURL();
          canvas = null;
          resolve(dataURL)
      }
      img.src = url;
    })
  }
  //for the demonstration purposes I used proxy server to avoid cross origin error
  const proxyUrl = 'https://cors-anywhere.herokuapp.com/'
  const image = await convertImgToBase64URL(proxyUrl+'https://image.shutterstock.com/image-vector/vector-line-icon-hello-wave-260nw-1521867944.jpg')
  console.log(image)
}
getImg64()


You can use this approach in any async function. Then you can just await for the converted image and continue with instructions.

Upvotes: 9

Chukwuemeka Maduekwe
Chukwuemeka Maduekwe

Reputation: 8526

Needed to leverage reader to convert blob to base64, prefer to use async-await syntax so I chose to extract reader logic into helper like this:

//* Convert resBlob to base64
export const blobToData = (blob: Blob) => {
  return new Promise((resolve) => {
    const reader = new FileReader()
    reader.onloadend = () => resolve(reader.result)
    reader.readAsDataURL(blob)
  })
}

and calling it using await in main code:

//* Convert resBlob to dataUrl and resolve
const resData = await blobToData(resBlob)

Upvotes: 2

井上智文
井上智文

Reputation: 2035

document.querySelector('input').onchange = e => {
  const fr = new FileReader()
  fr.onloadend = () => document.write(fr.result)
  fr.readAsDataURL(e.target.files[0])
}
<input type="file">

Upvotes: 2

Bhuwan Adhikari
Bhuwan Adhikari

Reputation: 1009

Here is the way you can do with Javascript Promise.

const getBase64 = (file) => new Promise(function (resolve, reject) {
    let reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result)
    reader.onerror = (error) => reject('Error: ', error);
})

Now, use it in event handler.

const _changeImg = (e) => {
        const file = e.target.files[0];
        let encoded;
        getBase64(file)
          .then((result) => {
            encoded = result;
           })
          .catch(e => console.log(e))
    }

Upvotes: 9

Mahedi Hasan
Mahedi Hasan

Reputation: 1068

uploadProfile(e) {

    let file = e.target.files[0];
    let reader = new FileReader();

    reader.onloadend = function() {
        console.log('RESULT', reader.result)
    }
    reader.readAsDataURL(file);
}

Upvotes: 8

James Harrington
James Harrington

Reputation: 3216

Here is what I did:

// Author James Harrington 2014
function base64(file, callback){
  var coolFile = {};
  function readerOnload(e){
    var base64 = btoa(e.target.result);
    coolFile.base64 = base64;
    callback(coolFile)
  };

  var reader = new FileReader();
  reader.onload = readerOnload;

  var file = file[0].files[0];
  coolFile.filetype = file.type;
  coolFile.size = file.size;
  coolFile.filename = file.name;
  reader.readAsBinaryString(file);
}

And here is how you use it

base64( $('input[type="file"]'), function(data){
  console.log(data.base64)
})

Upvotes: 28

Shubham
Shubham

Reputation: 2210

If you have a file object, this simple function will work:

function getBase64 (file, callback) {

    const reader = new FileReader();

    reader.addEventListener('load', () => callback(reader.result));

    reader.readAsDataURL(file);
}

Usage example:

getBase64(fileObjectFromInput, function(base64Data){
    console.log("Base64 of file is", base64Data); // Here you can have your code which uses Base64 for its operation, // file to Base64 by oneshubh
});

Upvotes: 12

ravi polara
ravi polara

Reputation: 572

Try this code:

For a file upload change event, call this function:

$("#fileproof").on('change', function () {
    readImage($(this)).done(function (base64Data) { $('#<%=hfimgbs64.ClientID%>').val(base64Data); });
});

function readImage(inputElement) {
    var deferred = $.Deferred();

    var files = inputElement.get(0).files;

    if (files && files[0]) {
        var fr = new FileReader();
        fr.onload = function (e) {
            deferred.resolve(e.target.result);
        };
        fr.readAsDataURL(files[0]);
    } else {
        deferred.resolve(undefined);
    }

    return deferred.promise();
}

Store Base64 data in hidden filed to use.

Upvotes: 4

Ajeet Lakhani
Ajeet Lakhani

Reputation: 3848

As far as I know, an image can be converted into a Base64 string either by FileReader() or storing it in the canvas element and then use toDataURL() to get the image. I had the similar kind of problem you can refer this.

Convert an image to canvas that is already loaded

Upvotes: 5

Vikash Pandey
Vikash Pandey

Reputation: 5443

Well, if you are using Dojo Toolkit, it gives us a direct way to encode or decode into Base64.

Try this:

To encode an array of bytes using dojox.encoding.base64:

var str = dojox.encoding.base64.encode(myByteArray);

To decode a Base64-encoded string:

var bytes = dojox.encoding.base64.decode(str);

Upvotes: 0

ThiefMaster
ThiefMaster

Reputation: 318458

You can use the HTML5 <canvas> for it:

Create a canvas, load your image into it and then use toDataURL() to get the Base64 representation (actually, it's a data: URL, but it contains the Base64-encoded image).

Upvotes: 234

user1801972
user1801972

Reputation:

This snippet can convert your string, image and even video file to Base64 string data.

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

Upvotes: 102

Artem Tikhomirov
Artem Tikhomirov

Reputation: 21676

You could use FileAPI, but it's pretty much unsupported.

Upvotes: 5

Related Questions