11

I get a buffer of data represent an image in Base64. The data I got (represent image in base64) (part of the data)

193,109,51,74,182,71,212,38,78,62,211,48,81,145,244,39,244,250,215,192,113,46,101,136,203,149,44,6,90,147,197,215,109,66,251,69,47,138,111,202,43,239,122,45,108,125,22,6,149,44,84,103,136,198,74,212,41,171,203,188,187,69,121,183,255,0,7,75,156,191,140,190,45,181,219,141,43,195,214,107,30,129,3,145,38,110,60,135,185,35,130,119,4,108,244,238,0,227,3,140,86,85,237,134,149,241,3,69,158,251,71,134,93,31,88,211,72,82,1,30,100,76,70,65,12,9,12,141,207,94,184,32,140,215,45,47,196,111,130,177,187,34,120,79,197,65,84,224,8,175,93,20,99,176,31,107,24,250,96,85,141,47,227,159,195,111,11,219,223,46,133,225,175,17,91,73,120,170,178,189,196,137,49,96,185,218,50,247,44,64,27,155,167,173,123,252,61,144,97,242,8,63,102,156,234,207,227,169,43,115,77,245,230,119,122,111,104,173,23,78,167,204,103,121,165,108,217,46,88,184,40,124.....

Successfully decode.

Now I'm trying to add the image to my canvas without success as following:

function fillCanvasImage(x, y, width, height, image, pageID) {
    if (image == "")
        return;

    var canvas = document.getElementById("AppPmainCanvas" + pageID);

    if (canvas && canvas.getContext) {
        var context = canvas.getContext('2d');
        if (context) {
            context.clearRect(0, 0, canvas.width, canvas.height);
            var img = new Image();
            img.src = base64_decode(image);
            //img.onload = function () {
                context.drawImage(img, 0, 0, canvas.width, canvas.height);
            //}
        }
    }
}

I'm convert the data form base64 by:

function base64_decode(data) {
    var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
        ac = 0,
        dec = "",
        tmp_arr = [];

    if (!data) {
        return data;
    }

    data += '';

    do { // unpack four hexets into three octets using index points in b64
        h1 = b64.indexOf(data.charAt(i++));
        h2 = b64.indexOf(data.charAt(i++));
        h3 = b64.indexOf(data.charAt(i++));
        h4 = b64.indexOf(data.charAt(i++));

        bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;

        o1 = bits >> 16 & 0xff;
        o2 = bits >> 8 & 0xff;
        o3 = bits & 0xff;

        if (h3 == 64) {
            tmp_arr[ac++] = String.fromCharCode(o1);
        } else if (h4 == 64) {
            tmp_arr[ac++] = String.fromCharCode(o1, o2);
        } else {
            tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
        }
    } while (i < data.length);

    dec = tmp_arr.join('');
    dec = utf8_decode(dec);

    return dec;
};

// private method for UTF-8 decoding
function utf8_decode(utftext) {
    var string = "";
    var i = 0;
    var c = 0,
        c1 = 0,
        c2 = 0;

    while (i < utftext.length) {
        c = utftext.charCodeAt(i);

        if (c < 128) {
            string += String.fromCharCode(c);
            i++;
        } else if ((c > 191) && (c < 224)) {
            c1 = utftext.charCodeAt(i + 1);
            string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
            i += 2;
        } else {
            c1 = utftext.charCodeAt(i + 1);
            c2 = utftext.charCodeAt(i + 2);
            string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
            i += 3;
        }
    }

    return string;
};

It does not work, I do the following: in my server side I convert the image as following:

public static string BitmapSourceToByteBase64(System.Windows.Media.Imaging.
{
    var encoder = new System.Windows.Media.Imaging.JpegBitmapEncoder();
    var frame = System.Windows.Media.Imaging.BitmapFrame.Create(source);
    encoder.Frames.Add(frame);
    var stream = new MemoryStream();

    encoder.Save(stream);
    return Convert.ToBase64String(stream.ToArray());
    //I tired to do return "data:image/name_jpg;base64,"+Convert.ToBase64String(stream.ToArray());
    //But got an exception on serialize base64 div 4 in the web client
}

in my website, I got the data (base64 image) and try to do the following: context.drawImage(0,0,'data:image/jpeg;base64,'+image); I also tried: context.drawImage('data:image/jpeg;base64,'+image,0,0);

NOT WORK!!! any idea?

2
  • BTW: I tried also : context.drawImage(0, 0, canvas.width, canvas.height, img); Commented Dec 12, 2011 at 10:57
  • I tried different way, see bellow Commented Dec 13, 2011 at 9:03

2 Answers 2

35

You don't need to "decode" a base64 string to draw it in a canvas, just assign it to an image source and draw that image in your canvas.

Something like this:

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var img = new Image();

img.onload = function() {
  context.drawImage(this, 0, 0, canvas.width, canvas.height);
}

img.src = "data:image/gif;base64,R0lGODlhDwAPAKECAAAAzMzM/////wAAACwAAAAADwAPAAACIISPeQHsrZ5ModrLlN48CXF8m2iQ3YmmKqVlRtW4MLwWACH+H09wdGltaXplZCBieSBVbGVhZCBTbWFydFNhdmVyIQAAOw==";
<canvas id="canvas" width="50" height="50"></canvas>

Make sure that your base64 string starts with the data:image/gif;base64, part.

image/jpeg, image/png, etc.. Depending on your encoded image format.

Sign up to request clarification or add additional context in comments.

3 Comments

This works for me in chrome and FF, it is failing in IE 9. setting the src attribute of img changes nothing, the image doesnt load correctly; any fixes suggested?
I made a fiddle and tested on Browerstack WIN7 IE9, no issues detected. jsfiddle.net/8fVvE
I'm sorry Pierre; This behaves as expected. I was running into a different bug where img 'src' is not allowed to be set inside an i-frame in IE9
1

http://localhost:994/%FF%...... cannot be drawn on canvas.
Your data sould look like "data:image/png;base64,iVBORw0..."
If they look like this then they are ready for use without base64 decoding. You simply draw them directly using context.drawImage

2 Comments

Do the following: draw an image from file on canvas and place its base64 representation in a variable using "var imgData = yourCanvasObject.toDataURL();". This will give you a clue of what is expected by the canvas and a comparison case for the data you generate.
I find the problem. I try few ways, then I change the contract to string instead of byte, and forget to change it in my client. this is the reason i get numbers instead of chars. And now it works - so I had 2 issues: 1. change the contract (api) to send string instead of byte[] 2. update the client reference

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.