0

I'm trying to compress an image with pngquant. Here is the code:

  let output = '';
  const quant = cp.spawn('pngquant', ['256', '--speed', '10'], {
    stdio: [null, null, 'ignore'],
  });

  quant.stdout.on('data', data => output += data);

  quant.on('close', () => {
    fs.writeFileSync('image.png', output);
    fs.writeFileSync('image_original.png', image);
    process.exit(0);
  });

  quant.stdin.write(image);

image is a Buffer with pure PNG data. The code works, however, for some reason, it generates incorrect PNG. Not only that, but also it's size is more than original's.

When I execute this from the terminal, I get excellent output file:

pngquant 256 --speed 10 < image_original.png > image.png

I have no idea of what's going on; the data in output file seems pretty PNG-ish.

EDIT: I have managed to make it work:

let output = [];

quant.stdout.on('data', data => output.push(data));
quant.stdin.write(image);

quant.on('close', () => {
  const image = Buffer.concat(output);

  fs.writeFileSync('image.png', image);
});

I assume that is related to how strings are represented in the NodeJS. Would be happy to get some explanation.

Efog
  • 1,155
  • 1
  • 15
  • 33
  • Where does `image` come from? – jfriend00 Nov 08 '21 at 02:20
  • @jfriend00 it comes from the `stdin` of the main process; the data is correct because I also save that as a PNG file. – Efog Nov 08 '21 at 02:22
  • So, you're waiting until you've gotten all the data from `stdin` before you execute any of this code? – jfriend00 Nov 08 '21 at 02:26
  • Yes. I managed to make it work, see the edit. – Efog Nov 08 '21 at 02:34
  • 1
    Treating it as a string probably assumes utf8 encoding which causes problems with pure binary data. As you discovered, you use Buffers for binary data. FYI, you just pipe the data directly to a file. You don't have to accumulate it all before writing it. – jfriend00 Nov 08 '21 at 02:39
  • The thing is that I don't need to store the data in a file. That was just an example. – Efog Nov 08 '21 at 06:04
  • FYI, you should not a solution into the question here on Stackoverflow. Instead, you should write your own answer and put the solution in the answer. – jfriend00 Nov 08 '21 at 22:33

0 Answers0