8

Like the title says, I have a byte array representing the contents of an image (can be jpeg or png).

I want to draw that on a regular canvas object

<canvas id='thecanvas'></canvas>

How can I do that?


UPDATE I tried this (unsuccesfully): (imgData is a png sent as a byte array "as is" through WebSockify to the client)

function draw(imgData) {
    "use strict";

    var canvas = document.getElementById("myCanvas");
    var ctx = canvas.getContext("2d");
    var rdr = new FileReader();
    var imgBlob = new Blob([imgData], {type: "image/png"});
    rdr.readAsBinaryString(imgBlob);

    rdr.onload = function (data) {
        console.log("Filereader success");
        var img = new Image();
        img.onload = function () {
            console.log("Image Onload");
            ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
        };
        img.onerror = function (stuff) {
            console.log("Img Onerror:", stuff);
        };
        img.src = "data:image/png;base64," + window.btoa(rdr.result);
    };

}

I always reach img.onerror()

Also After reading the file with a HEX editor on my file system, I can see that the byte array is identical to the original file.

Charles
  • 50,943
  • 13
  • 104
  • 142
Ben
  • 10,020
  • 21
  • 94
  • 157
  • Have you seen this: http://stackoverflow.com/questions/12041851/converting-bytes-to-an-image-for-drawing-on-a-html5-canvas ? – Hauns TM Jan 29 '14 at 14:47
  • @HaunsTM No! Thanks. I'm looking into that. If that solves my problem I will delete the question – Ben Jan 29 '14 at 14:53
  • You need to tell us a little about what format your byte array is in: is it raw pixels and in that case how are they ordered (RGB, RGBA, BGR etc.), if not, are they representing an encoded image and if so which encoding (Base-64, raw compressed JPEG/PNG)? –  Jan 29 '14 at 18:52
  • @Ken I know for sure that its a png file that is read on the client and sent "as is". It is passed through WebSockify on the server side (as a proxy) and I'm not sure what WebSockify does with it. – Ben Jan 30 '14 at 06:08
  • Is it worth mentioning that you're asking for and encoding a PNG file, before telling the browser that you're sending a JPEG one? – enhzflep Jan 30 '14 at 07:14
  • @enhzflep Thanks for that. I changed it. Same thing happens... – Ben Jan 30 '14 at 07:19

1 Answers1

9

This Works:

function draw2(imgData, coords) {
    "use strict";
    var canvas = document.getElementById("myCanvas");
    var ctx = canvas.getContext("2d");

    //var uInt8Array = new Uint8Array(imgData);
    var uInt8Array = imgData;
    var i = uInt8Array.length;
    var binaryString = [i];
    while (i--) {
        binaryString[i] = String.fromCharCode(uInt8Array[i]);
    }
    var data = binaryString.join('');

    var base64 = window.btoa(data);

    var img = new Image();
    img.src = "data:image/png;base64," + base64;
    img.onload = function () {
        console.log("Image Onload");
        ctx.drawImage(img, coords[0], coords[1], canvas.width, canvas.height);
    };
    img.onerror = function (stuff) {
        console.log("Img Onerror:", stuff);
    };

}
Ben
  • 10,020
  • 21
  • 94
  • 157
  • This actualy works but what if I want to keep the proportions from the original image? – Gera4463 Feb 11 '14 at 15:59
  • Done, you can meassure the img and do the math, Thanks – Gera4463 Feb 11 '14 at 21:28
  • I removed the width/height attrs from canvas and set them in the onload method before drawing the image and this scaled the image properly from 300x150 to 640x480. Initially the image was only being displayed in 300x150 even though the browser thought it was 640x480.: image.onload = function() { canvas.width = image.width; canvas.height = image.height; context.drawImage( image,0,0, canvas.width, canvas.height ); – Bob Feb 14 '16 at 22:41
  • coords is not defined? – Rune Jeppesen Sep 02 '16 at 19:51