5

I'm trying to encode an image to base64 and send it to a server. When I retrieve the image all it shows is blank.

The code I'm using to encode it is this:

encodeImageUri = function(imageUri) {
        var c = document.createElement('canvas');
        var ctx = c.getContext("2d");
        var img = new Image();
        img.onload = function() {
            c.width = this.width;
            c.height = this.height;
            ctx.drawImage(img, 0, 0);
        };
        img.src = imageUri;
        var dataURL = c.toDataURL("image/jpeg");

        return dataURL.slice(22, dataURL.length);
    }

Taken from: Using PhoneGap, How to get base64 image data of the photo chosen from photo library in iPhone

Community
  • 1
  • 1
danielrvt-sgb
  • 1,118
  • 5
  • 17
  • 33

3 Answers3

3

I use the following code to convert an image to Base64:

var Base64 = {
    /**
     * This implementation relies on Cordova 1.5 or above implementations.
     */
    getBase64ImageFromInput : function (input, callback) {
        var imageReader = new FileReader();
        imageReader.onloadend = function (evt) {
            if (callback)
                callback(evt.target.result);
        };
        //Start the asynchronous data read.
        imageReader.readAsDataURL(input);
    },
    formatImageSrcString : function (base64) {
        return (base64.match(/(base64)/))? base64 : "data:image/jpeg;base64," + base64;
    } 
};

Below is an example using this object to convert an image from a file input to base64 encoding:

var fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.onchange = function () {
    var input = this.files[0];
    if (input) {
        Base64.getBase64ImageFromInput(input, function (imageData) {
            //Process the image string. 
            console.log(imageData);
        });
    } else {
       alert("Please select an image.");
    }
};

Hope this helps. Let me know if you have any questions.

Zorayr
  • 23,770
  • 8
  • 136
  • 129
2

The image is loading asynchronously, meaning that your return dataURL... happens before the image is loaded into the canvas.

Instead of having this function return a value, have it call a callback function.

encodeImageUri = function(imageUri, callback) {
    var c = document.createElement('canvas');
    var ctx = c.getContext("2d");
    var img = new Image();
    img.onload = function() {
        c.width = this.width;
        c.height = this.height;
        ctx.drawImage(img, 0, 0);

        if(typeof callback === 'function'){
            var dataURL = c.toDataURL("image/jpeg");
            callback(dataURL.slice(22, dataURL.length));
        }
    };
    img.src = imageUri;
}

You now call it like this:

encodeImageUri('/path/to/image.png', function(base64){
    // Do something with the b64'd image
});

NOTE: For this to work, the image needs to be on the same domain as your page.

gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • @danielrvt-sgb: Is the image on the same domain as your page? Are you sure that string is wrong? – gen_Eric Jan 11 '13 at 21:11
  • The image is taken with the phone camera and store in the sdcard. I tested the string in this page: http://www.freeformatter.com/base64-encoder.html and returns a blank image – danielrvt-sgb Jan 11 '13 at 21:18
  • I don't know anything about phonegap, but I know *browsers* don't like it when you try to load files from the filesystem into the page. – gen_Eric Jan 11 '13 at 21:24
2

Use the readAsDataURL method of FileReader.

Simon MacDonald
  • 23,253
  • 5
  • 58
  • 74