1

I'm trying to use node-canvas to manipulate an image stored on a remote server. I started with the image-src example and modified it, but I can't get it to work. Here's my code:

var fs = require('fs'),
    http = require('http'),
url = require('url'),
canvas = require('./node-canvas/lib/canvas');

var outCanvas = new canvas(1000, 750);
var ctx = outCanvas.getContext('2d');

http.get(
    {
        host: 'farm8.staticflickr.com',
        port: 80,
        path: '/7108/7038906747_69a526f070_z.jpg'
    },
    function(res) {
        var data = '';
        res.on('data', function(chunk) {
            data += chunk;
        });
        res.on('end', function () {
            img = new canvas.Image;
            img.src = data;
            ctx.drawImage(img, 0, 0, img.width, img.height);

            var out = fs.createWriteStream(__dirname + '/my-out.png')
                , stream = outCanvas.createPNGStream();

            stream.on('data', function(chunk){
                out.write(chunk);
            });
        });
    }
);

...and here's the error I'm getting:

/Users/daf/Documents/lolstagram/lolstagram-c.js:23
    ctx.drawImage(img, 0, 0, img.width, img.height);
       ^
Error: Image given has not completed loading
    at IncomingMessage.<anonymous> (/Users/daf/Documents/lolstagram/lolstagram-c.js:23:8)
    at IncomingMessage.emit (events.js:88:20)
    at HTTPParser.onMessageComplete (http.js:137:23)
    at Socket.ondata (http.js:1150:24)
    at TCP.onread (net.js:374:27)

Any idea what the problem might be? Thanks.

Dave Feldman
  • 104
  • 1
  • 9
  • 28

2 Answers2

1

You're treating the data in the response as a String when you need to keep it as binary data in a Buffer. Node-canvas is expecting binary data to be passed into img.src.

This should work inside your http response handler:

var data = new Buffer(parseInt(res.headers['content-length'],10));
var pos = 0;
res.on('data', function(chunk) {
  chunk.copy(data, pos);
  pos += chunk.length;
});
res.on('end', function () {
  img = new canvas.Image;
  img.src = data;
  ctx.drawImage(img, 0, 0, img.width, img.height);
  var out = fs.createWriteStream(__dirname + '/my-out.png')
    , stream = outCanvas.createPNGStream();

  stream.on('data', function(chunk){
    out.write(chunk);
  });
});
jimr
  • 11,080
  • 1
  • 33
  • 32
  • Hi, I used your code and still got the same message, ctx.drawImage(img, 0, 0, img.width, img.height); ^ Error: Image given has not completed loading at IncomingMessage. (/Users/jiguang/www/node/api.js:25:17) at IncomingMessage.EventEmitter.emit (events.js:117:20) at _stream_readable.js:920:16 at process._tickCallback (node.js:415:13), is there any other problems? thank you! – jiguang Nov 17 '13 at 02:54
1

It must be the jpg problem (I have no idea) I think it will be ok if your image is png

Please install libjpeg to fix the issue :)

Ddo
  • 389
  • 3
  • 12