Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading binary data from a child process in Node.js

When trying to read data in Node.js from an ImageMagick child process, it comes out corrupted.

A simple test case would be the following:

var fs = require('fs');
var exec = require('child_process').exec;

var cmd = 'convert ./test.jpg -';
exec(cmd, {encoding: 'binary', maxBuffer: 5000*1024}, function(error, stdout) {
  fs.writeFileSync('test2.jpg', stdout);
});

I would expect that to be the equivalent of the command line convert ./test.jpg - > test2.jpg that does write the binary file correctly.

Originally there was a problem with the maxBuffer option being too small and resulting in a truncated file. After increasing that, the file now appears slightly larger than expected and still corrupted. The data from stdout is required to send over HTTP.

What would be the correct way to read this data from the ImageMagick stdout?

like image 295
Daniel Cremer Avatar asked May 28 '11 20:05

Daniel Cremer


People also ask

What is binary data in Nodejs?

Binary is simply a set or a collection of 1 and 0 . Each number in a binary, each 1 and 0 in a set are called a bit. Computer converts the data to this binary format to store and perform operations. For example, the following are five different binaries: 10, 01, 001, 1110, 00101011.

How do you convert node JS to binary?

Try this . var fs = require("fs"); fs. readFile('image. jpg', function(err, data) { if (err) throw err; // Encode to base64 var encodedImage = new Buffer(data, 'binary').

Could we run an external process with node js?

To execute an external program from within Node. js, we can use the child_process module's exec method. const { exec } = require('child_process'); exec(command, (error, stdout, stderr) => { console.


1 Answers

There were two problems with the initial approach.

  1. The maxBuffer needs to be high enough to handle the whole response from the child process.

  2. Binary encoding needs to be properly set everywhere.

A full working example would be the following:

var fs = require('fs');
var exec = require('child_process').exec;

var cmd = 'convert ./test.jpg -';
exec(cmd, {encoding: 'binary', maxBuffer: 5000*1024}, function(error, stdout) {
  fs.writeFileSync('test2.jpg', stdout, 'binary');
});

Another example, sending the data in an HTTP response using the Express web framework, would like this:

var express = require('express');
var app = express.createServer();

app.get('/myfile', function(req, res) {
  var cmd = 'convert ./test.jpg -';
  exec(cmd, {encoding: 'binary', maxBuffer: 5000*1024}, function(error, stdout) {
     res.send(new Buffer(stdout, 'binary'));
  });
});
like image 155
Daniel Cremer Avatar answered Oct 19 '22 12:10

Daniel Cremer