Hugolpz Hugolpz - 1 year ago 327
Javascript Question

JS: how to encode an image.png into base64 code for data URI embedding?

I have several .png bitmaps of different dimensions, by example

. How to load the
string of my images via JS ?
My expected data is omething like that (but far longer):


Note: I wish to get back this string which is my file and just my file, not clipped, nor bigger. I will then embedded it into a SVG
element such:

<image href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAB9AYAAACaOMR5AAAgAElyuiRTYUdG

My end project looks will look like that :)

enter image description here

See also: , where you can download the SVG, but the png is currently just a link and will not get downloaded.


OK. The solution is in this fiddle and explained as follows.

0) Objective: I wish to append something such :

<img src="data:[mime type;][charset=<charset>;][base64,][base64 data]"> // formula
<image src='data:image/png;base64,SGVsbG8s...IHdvcmxkIQ='></image>" // shortened example

1) PNG images to base 64.

PNGs are stored as BLOB, aka "a collection of binary data stored as a single entity". So I need a BLOB to Base64 converter :

var converterEngine = function (input) { // fn BLOB => Binary => Base64 ?
    var uInt8Array = new Uint8Array(input),
          i = uInt8Array.length;
    var biStr = []; //new Array(i);
    while (i--) { biStr[i] = String.fromCharCode(uInt8Array[i]);  }
    var base64 = window.btoa(biStr.join(''));
    return base64;

2) Loading the file and converting (data)

var getImageBase64 = function (url, callback) {
    // to comment better
    var xhr = new XMLHttpRequest(url), img64;'GET', url, true); // url is the url of a PNG/JPG image.
    xhr.responseType = 'arraybuffer';
    xhr.callback = callback;
    xhr.onload  = function(){
        img64 = converterEngine(this.response); // convert BLOB to base64
        this.callback(null,img64) // callback : err, data
    xhr.onerror = function(){ callback('B64 ERROR', null); };

// make it looks like other D3js requests
d3.uri = function(url, callback) {
    return getImageBase64(url, callback);

3) Run the whole:

I run the function with the callback to append an image element with the base64 URI data.

d3.uri('', function(data){ 
    $("#myImage").attr("src", "data:image/png;base64," + data);  // inject data:image in DOM
} )

Sources: I got help from Getting BLOB data from XHR request, then demoed there.

Server side

I may actually end up using server-side conversion (sources this and this). Possible ways are :

echo -n `cat file.png` | base64 > output.txt
openssl base64 < path/to/file.png | tr -d '\n' > output.txt
cat path/to/file.png | openssl base64 | tr -d '\n' > output.txt
openssl base64 -in input.png -out output.txt