Search code examples
javascriptnode.jssocketsintelintel-galileo

Dynamically display an image using Node.js with socket.io and fs


I am running Node.js on an Intel Galileo Gen 2 as part of my final year project and I am trying to use the Galileo to take a picture using a webcam and serve the picture taken every time to the web page using a canvas element.

This is the code on the Node.js server:

    // this 'message' event receives the sketch datagram 
server.on("message", function (msg, rinfo) { 
    udp_msg = msg.toString();     
    if(udp_msg == "picTaken") {
                    fs.readFile(__dirname + '/pictures/pic'+picNum+'.jpg', function(err, buf){

                    io.emit('image', { image: true, buffer:         buf.toString('base64') });
                    console.log('image file is initialized' + picNum);
                    picNum++;
                });
    }
    //console.log("from " + rinfo.address + " message:" + udp_msg);     
    // just bypassing the message sent by the sketch     
    io.emit("server-event-info", udp_msg);
});

The sketch running on the galileo send the string "picTaken" to the server which causes this function to be invoked and this is the code on the html page to display the image:

<div class="pic">
        <canvas id="img"  width="280" height="220" style="border:1px solid #000000;">
            Your browser does not support the HTML5 canvas tag.
        </canvas>
    </div> 
    <script>
        var ctx = document.getElementById('img').getContext('2d');
        socket.on("image", function(info) {
          if (info.image) {
            var img = new Image();
            img.src = 'data:image/jpeg;base64,' + info.buffer; 
            ctx.drawImage(img, 0, 0);
            console.log("Image received");
          }
        });
    </script>

The problem is that the image appears to be received by the browser because it is printing 'image received' to the console but it is not displaying. It works if I try to statically display an image, say by replacing the line

  fs.readFile(__dirname + '/pictures/pic'+picNum+'.jpg', function(err, buf){

with

fs.readFile(__dirname + '/pictures/pic1.jpg', function(err, buf){

So I don't see what the issue is


Solution

  • I discovered that the problem was the image was being received by the client but I was not waiting for it load before I tried to display it. I changed my code on the client side to wait for the image to load and then display the image and it worked. Here is the code on the client side now:

    var ctx = document.getElementById('img').getContext('2d');
        socket.on("image", function(info) {
          if (info.image) {
            var img = new Image();
            img.onload = function () {
                ctx.drawImage(img, 0, 0);
            };
            img.src = 'data:image/jpg;base64,' + info.buffer;   
            console.log("Image received");
          }
        });