0

I try to catch the completion of writing the canvas stream thusly:

    var out = fs.createWriteStream(out_fs);
    var stream = canvas.createPNGStream({
        bufsize: 2048
    });
    stream.on('end', function () {
      // can we use out_fs now? why not?
    });
    stream.pipe(out);

But when I try to load out_fs in sub function

Error: Image given has not completed loading

at this line:

            fs.readFile(out_fs, function (err, data) {
                    if (err) throw err;
                    var img = new Canvas.Image; // Create a new Image
                    img.src = data;
                    ctx2.drawImage(img, 0, 50, img.width, img.height); <--

http://nodejs.org/api/stream.html#stream_event_end

But I don't see any other way to continue with the control flow after the stream is written. If I let the entire parent function return, the file then seems readable. I've tried wrapping my child functions in setImmediate(), but that only seems to work intermittently.

What is the definitive way to catch the final usable end result of writing the stream?

The node-canvas documentation claims that the end event signals the final writing of the file: https://www.npmjs.com/package/canvas#canvaspngstream

But this generates the error above if you immediately try to use it.

`finish' does not seem to be implemented at all.

metalaureate
  • 7,572
  • 9
  • 54
  • 93
  • You'd think that would work, but it never gets called at all. – metalaureate Feb 16 '15 at 21:14
  • 1
    `.on('end')` should be enough, I think you should post more code, as there may be a control flow problem (something running before you think, etc). – aarosil Feb 16 '15 at 21:16
  • @aarosil ok I am not proud of the pyramid of doom - you are probably right. But in essence I am generating one canvas object, and then I generate a second canvas object which is a montage of the first + two external img files. http://pastebin.com/E0J1QTvr – metalaureate Feb 16 '15 at 21:21
  • 1
    Couple of things, you can always use `fs.readFileSync()`, to eliminate callbacks (it will block other code execution however). It seems like some image names are hardcoded you can read those files w/ `sync` at top of script and preserve those results. Should make it easier for you to debug further, at least – aarosil Feb 16 '15 at 21:39
  • 1
    Can you try replace `stream.on('end', ...)` above, with `out.on('close', ...)` an see what happens? – aarosil Feb 16 '15 at 22:34
  • @aarosil That worked. I was utterly confused about which stream I needed to piggy back off. Thank you so much! Feel free to answer. – metalaureate Feb 16 '15 at 23:40

2 Answers2

1

I would put this in a comment (but can't):

You need to close your WriteStream called 'out' - use the event aarosil suggests and do out.close()

diversemix
  • 569
  • 2
  • 12
1

Since you have piped stream to out, out will be close()'d automatically on stream's end event (this is part of what gets setup automatically when you .pipe() a stream). So, to know when file is finished being written, listen to the close event of out stream.

You saw intermittent results because the stream end event is the same event that will be used by out writable stream to finalize the file.

aarosil
  • 4,848
  • 3
  • 27
  • 41