27

Is there any plain and straight forward examples on how to serve an image? from server to client? through buffering or just a direct call to download? (the goal is to get image files in near real time efficiently to sort of present a near live stream of images) and append to a html image tag or just in the body of the html page.

incomplete sample code: (mostly acquired from official sample or just codes from stackoverflow)

index.js

// basic variables
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

var fs = require('fs'); // required for file serving

http.listen(3000, function(){
  console.log('listening on *:3000');
});

// location to index.html
app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');
});

// only to test chat sample code from sample
io.on('connection', function(socket){

  console.log('a user connected');
    // broadcast a message
  socket.broadcast.emit('chat message', 'System Broadcast Message: a user has been connected');
  socket.on('chat message', function(msg){
    io.emit('chat message', msg);
  });

// trying to serve the image file from the server
io.on('connection', function(socket){
  fs.readFile(__dirname + '/images/image.jpg', function(err, buf){
    // it's possible to embed binary data
    // within arbitrarily-complex objects
    socket.emit('image', { image: true, buffer: buf });
    console.log('image file is initialized');
  });
});

(client side html page) index.html (we'll cut to the chase with only the portion which serves the image) What can we do on the client side to get the file and serve the image on the html page?

  socket.on("image", function(image, buffer) {
     if(image)
     {
         console.log(" image: from client side");
         // code to handle buffer like drawing with canvas** <--- is canvas drawing/library a requirement?  is there an alternative? another quick and dirty solution?
        console.log(image);
        // what can we do here to serve the image onto an img tag?
     }

 });

thank you for reading


Update:

after the code snippets from below it also needed to change "buffer" variable to image.buffer in order for the image to display correctly

basically change the line from

img.src = 'data:image/jpeg;base64,' + buffer;

To

img.src = 'data:image/jpeg;base64,' + image.buffer;
Bigs
  • 616
  • 2
  • 11
  • 17

1 Answers1

42

One possible solution is to base64-encode the image data and use that in the browser via image.src:

On the server side, try changing this:

socket.emit('image', { image: true, buffer: buf });

to this:

socket.emit('image', { image: true, buffer: buf.toString('base64') });

Then on the client side:

var ctx = document.getElementById('canvas').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);
  }
});
mscdex
  • 104,356
  • 15
  • 192
  • 153
  • thanks, i was able to get it work with your snippets and changing the variable from buffer to image.buffer! like this: img.src = 'data:image/jpeg;base64,' + image.buffer; thanks! for the help! – Bigs Oct 13 '14 at 02:40
  • 1
    @mscdex this base64 method of sending images work for me ,but in my chat app, whenever I try to send a large image such as over 3 mb and with over 1k dimensions, then everytime the socket io disconnects the chat , nay be due to my slow upload speed of internet. is there a nicer and scalable way to upload image or files to server and display to client in a light way which can handle large file uploads too.? – Faizan May 15 '19 at 12:55