2

I've tried several different options, so many I've lost track of them all. I'm making an AJAX request and the response is of Content-Type: image/png, and the contents are the actual image.

I would absolutely love to display the image, but nothing seems to work the way I want:

// imgdata contains a string that looks like this: "�PNG..."
var img = document.createElement('img');

// no good
img.src = 'data:image/png;base64,' + btoa(unescape(encodeURIComponent(data)));

// also no good
img.src = 'data:image/png;base64,' + btoa(encodeURIComponent(data));

// also no good
img.src = 'data:image/png;base64,' + btoa($.map(d, function(x){ return x.charCodeAt(0); }))

I've tried a few other things, but still no dice.

Is there any simple (or even complciated) way to do this in Javascript?

Wayne Werner
  • 49,299
  • 29
  • 200
  • 290
  • This question has already been asked here : http://stackoverflow.com/questions/6150289/how-to-convert-image-into-base64-string-using-javascript and here http://stackoverflow.com/questions/934012/get-image-data-in-javascript – Sparkup Feb 03 '15 at 15:32
  • @Sparkup that involves the canvas element which is *not* just Javascript. For IE it's [only supported as far back as 9](http://caniuse.com/#search=canvas). If you have to support 8 (or earlier) that solution just won't work. – Wayne Werner Feb 03 '15 at 16:29
  • It also appears that `toData` [doesn't always work](http://stackoverflow.com/questions/10488033/todataurl-not-working-on-android-browsers) – Wayne Werner Feb 03 '15 at 16:32
  • The other solution is to use `FileReader` which is even less-well supported. – Wayne Werner Feb 03 '15 at 16:35
  • Ok seems it hasn't been answered, so sorry. I have made myself useful however by adding an answer :) – Sparkup Feb 03 '15 at 21:18

2 Answers2

0

If you're serving this file via node.js or PHP you could always write the file to disk in temporary location server-side, serve it, and then immediately delete it afterwards.

var tempFile = 'path/to/file.jpg';

// Write the file to disk
fs.writeFile(tempFile, base64versionOfPhoto, function (err) {
    if (err) {
        res.header("Content-Type","application/json");
        return res.send(JSON.stringify(err));   
    } else {
        // Pipe the jpg to the user
        res.header("Content-Type","image/jpeg");

        var readStream = fs.createReadStream(tempFile);
        readStream.pipe(res, {end: false});

        readStream.on("end", function () {
            res.end();

            // Delete the file
            fs.unlink(tempFile, function (err) {
                if (err) console.log(err);
            });
        });
    }
});
jake_nerdnest
  • 402
  • 4
  • 10
  • *note* it doesn't necessarily have to be node.js or PHP, those were meant to be examples. My code provided is node.js btw – jake_nerdnest Feb 03 '15 at 15:11
  • Hmmm. That might be a workaround. I'm using Java, ugh, or I'd just convert things server side – Wayne Werner Feb 03 '15 at 15:19
  • I came across this problem when I was trying to display photos from an LDAP server, which were in base64. After numerous attempts like you, I found that the best way was to have the server "create" the file long enough for it to be served to the client. You should definitely be able to do something similar from Java. – jake_nerdnest Feb 03 '15 at 16:03
0

This isn't done with base64 but with blob, but you'll get exactly the same result:

var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function(){
        if (this.readyState == 4 && this.status == 200){
            var img = document.getElementById('image');
            var url = window.URL || window.webkitURL;
            img.src = url.createObjectURL(this.response);
        }
    }
    // Relative path because : 
    // No 'Access-Control-Allow-Origin' header is present...
    xhr.open('GET', '/img/logo.png');
    xhr.responseType = 'blob';
    xhr.send();

Demo here : http://jsfiddle.net/sparkup/sp4cukee/

Sparkup
  • 3,686
  • 2
  • 36
  • 50