这个问题背后的上下文是我正在获取一个图像缓冲区,并使用 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 添加 header 统计数据。
为了获得sizeAfter
,我尝试了 length-stream module ,您可以在其中将监听器插入管道(在 myPngQuanter
和 res
之间)以确定其通过的长度。虽然这似乎确实可以确定压缩流的长度,但它并没有及时向 res
添加任何 header 。我也尝试过stream-length ,但根本无法让它工作。
感谢任何帮助。
最佳答案
流本质上并没有真正的长度信息(流可以是无限的,例如打开/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);
关于node.js:在将流传输到最终目的地之前确定流的长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54008318/