1

这个问题背后的背景是我正在获取一个图像缓冲区,用pngquant对其进行压缩,然后将压缩图像传递给响应。就像是:

// https://www.npmjs.com/package/pngquant
const PngQuant = require('pngquant'); 

// start with base64-encoded png image data:
var base64data = '.......';

// then create buffer from this, as per:
//   https://stackoverflow.com/a/28440633/4070848
//   https://stackoverflow.com/a/52257416/4070848
var imgBuffer = Buffer.from(base64data, 'base64');

// set up pngquant...
const optionsArr = [ ..... ];
const myPngQuanter = new PngQuant(optionsArr);

// convert buffer into stream, as per:
//   https://stackoverflow.com/a/16044400/4070848
var bufferStream = new stream.PassThrough();
bufferStream.end(imgBuffer);

// pipe the image buffer (stream) through pngquant (to compress it) and then to res...
bufferStream.pipe(myPngQuanter).pipe(res);

我想确定 pngquant 操作实现的压缩比。我可以很容易地找到起始尺寸:

const sizeBefore = imgBuffer.length;

我还需要压缩流的大小。此外,在将流传输到目标之前,此信息必须可用,res因为我需要res根据压缩统计信息添加标头。

为此sizeAfter,我尝试了length-stream 模块,您可以在其中将侦听器插入管道(在myPngQuanter和之间res)以确定它通过时的长度。虽然这似乎确实可以确定压缩流的长度,但不会及时将任何标头添加到res. 我也尝试过stream-length,但根本无法让它工作。

任何帮助表示赞赏。

4

1 回答 1

2

好吧,流本质上并没有真正的长度信息(流可以是无限的,例如 opens /dev/random),所以我能看到的最简单的选择是使用另一个临时缓冲区。不幸的是,pngquant没有对缓冲区进行操作的选项,但是除了完全使用不同的包之外,您对此无能为力。

第二次编辑,因为流缓冲区可能不起作用:

有一个名为 的包stream-to-array,它允许轻松实现流到缓冲区的转换。根据README,代码应修改为:

const toArray = require('stream-to-array');
const util = require('util');
toArray(bufferStream.pipe(myPngQuanter))
.then(function (parts) {
  const buffers = parts
    .map(part => util.isBuffer(part) ? part : Buffer.from(part));
  const compressedBuffer = Buffer.concat(buffers);
  console.log(compressedBuffer.length); // here is the size of the compressed data
  res.write(compressedBuffer);
});

或者await,如果你碰巧在一个async上下文中:

const toArray = require('stream-to-array');
const util = require('util');
const parts = await toArray(bufferStream.pipe(myPngQuanter));
const buffers = parts.map(part => util.isBuffer(part) ? part : Buffer.from(part));
const compressedBuffer = Buffer.concat(buffers);
console.log(compressedBuffer.length); // here is the size of the compressed data
res.write(compressedBuffer);
于 2019-01-02T14:55:28.463 回答