senty
senty

Reputation: 12847

javascript image base64 and php image base64_encode are different

I have an jpeg image and I am trying to get the base64 encoded string with both javascript & php.

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/jpg");
  return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}

var base64 = getBase64Image(document.getElementById('myImg'));
console.log(base64)

Here is the javascript fiddle.


Now, with the same image with php code

$url = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/SIPI_Jelly_Beans_4.1.07.tiff/lossy-page1-256px-SIPI_Jelly_Beans_4.1.07.tiff.jpg" 

var_dump(base64_encode(file_get_contents($url));

// The Javascript result:
"iVBORw0KGgoAAAANSUh......LGoT8H4JpIaDthj+xAAAAAElFTkSuQmCC"

// The PHP result:
"/9j/4AAQSkZJRgABAQA......nbKBwJCElGEDnboCdvdE5pDlGThLlNC/9k="

I made the changes in Javascript that @JaromandaX suggested, now the Javascript string's beginning looks similar but not the end.

var dataURL = canvas.toDataURL("image/jpeg");
return dataURL.replace(/^data:image\/(png|jpeg);base64,/, "");

New Javascript Output: "/9j/4AAQSkZJRgABAQA......A4EhCSjCBzt0BO3uic0hyjccJcpoX//2Q=="

Upvotes: 3

Views: 3630

Answers (2)

senty
senty

Reputation: 12847

As @JaromandaX suggested in the comments,

"One is the direct file from the source (PHP) ... the other is a canvas - so, some "processing" has been done most likely"

Using this chunk gives the exact same base64 string:

var url = document.getElementById('myImg').getAttribute('src')
var xmlHTTP = new XMLHttpRequest();
xmlHTTP.open('GET', url, true);
xmlHTTP.responseType = 'arraybuffer';
xmlHTTP.onload = function(e) {
  var arr = new Uint8Array(this.response);
  var raw = String.fromCharCode.apply(null,arr);
  var b64 = btoa(raw);
  var dataURL="data:image/png;base64," + b64;
  console.log(b64)
};
xmlHTTP.send();

Upvotes: 1

Jaromanda X
Jaromanda X

Reputation: 1

The issue is, you're reading a jpeg into the canvas, then producing the jpeg from the canvas ... so there's some processing going on (jpeg quality setting for example would be different)

To get identical results in javascript, simply don't use a canvas - fetch the image, and using Blob + FileReader, extract the base64

fetch('https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/SIPI_Jelly_Beans_4.1.07.tiff/lossy-page1-256px-SIPI_Jelly_Beans_4.1.07.tiff.jpg').then(r => r.blob()).then(blob => {
    var reader = new FileReader();
    reader.onload = function() {
        var b64 = reader.result.replace(/^data:.+;base64,/, '');
        console.log(`${b64.slice(0,20)}...${b64.slice(-20)}`);
    };
    reader.readAsDataURL(blob);
});

Upvotes: 4

Related Questions