在 Node.js 中读取 PNG 图像

24

在Node.js中有没有一种简单的方法来读取PNG文件并获取图像的像素?就像node-image这样的东西,但是反过来 :)

我研究了https://github.com/joyent/node/wiki/modules#wiki-graphics列出的库,但它们要么是围绕命令行工具提供裁剪和缩放的简单包装器,要么是像 node-canvas 这样的复杂绘图工具。


2
为什么“node-canvas”对你无效?将png推入画布,然后在画布中探测像素:http://falcon80.com/HTMLCanvas/PixelManipulation/getImageData.html - user1207456
3
@david-ellis 谢谢,我可能会使用这个,但我想知道是否有一个仅读取图像的库。整个带有Cairo渲染的画布似乎有点过度了。 - Jan Špaček
1
谢谢提供信息,@jmendeth。我确实说过我不认为这样的库存在,但我并没有说我搜索过。 - user1207456
@honzasp 顺便说一下,如果你找到了一个解决你问题的答案,请点击它的绿色勾选标志来接受它。谢谢! - Alba Mendez
@DavidEllis 哦,抱歉如果我听起来很粗鲁。这绝不是我的意图。 - Alba Mendez
显示剩余2条评论
3个回答

28

这个可以同时进行PNG解码和编码,而不需要原生依赖:

pngjs - 一款适用于Node.js的PNG编码器/解码器,无需使用原生依赖。

一个反转PNG颜色的例子:

var fs = require('fs'),
PNG = require('pngjs').PNG;

fs.createReadStream('in.png')
  .pipe(new PNG())
  .on('parsed', function() {

    for (var y = 0; y < this.height; y++) {
        for (var x = 0; x < this.width; x++) {
            var idx = (this.width * y + x) << 2;

            // invert color
            this.data[idx] = 255 - this.data[idx]; // R
            this.data[idx+1] = 255 - this.data[idx+1]; // G
            this.data[idx+2] = 255 - this.data[idx+2]; // B

            // and reduce opacity
            this.data[idx+3] = this.data[idx+3] >> 1;
        }
    }

    this.pack().pipe(fs.createWriteStream('out.png'));
});

不好意思,能否请您看一下我在这里提出的问题:https://stackoverflow.com/questions/46186815/noise-in-png-produced-by-pngjs-for-nodejs?我使用pngjs生成的PNG图片存在噪点问题,希望能得到帮助。 - kolyaseg

16
我差点因为寻找而抓狂,但我找到了一个:

png.js ― 适用于canvas元素或Node.js的JS PNG解码器。

var PNG = require('png-js');

var myimage = new PNG('myimage.png');

var width  = myimage.width;
var height = myimage.height;

myimage.decode(function (pixels) {
    //Pixels is a 1D array containing pixel data
});

请注意这是纯JavaScript。可以在浏览器中的和Node.JS中使用。除了width和height之外,还有更多属性,请参见this source

1
啊哈,谢谢,这很接近;但我认为PNG构造器期望图像的实际字节,所以你必须自己读取文件。如果你提供了错误的数据,它可能会陷入无限循环,它甚至不检查PNG头,所以要小心使用这个库! - Jan Špaček
好的,README文件中说你可以给它一个路径或者一个Buffer。事实上,我一直在使用new PNG('image.png')而没有任何问题。但是知道这点也很好! - Alba Mendez
1
我刚刚测试了上面答案中的源代码(使用现有图像的路径),但是我得到了以下错误:/home/anderson/node_modules/png-js/png-node.js:140 throw new Error("Incomplete or corrupt PNG file");。我指定了现有图像的路径,那么为什么会发生这种情况呢? - Anderson Green
我认为这已经过时了(至少在Node上),请改用node-pngjs。它具有更多的功能,如编码和增量处理。请参见下一个答案。 - Alba Mendez
这个库仍然可以正常工作。它非常适合用于非常小的简单脚本。 - Qix - MONICA WAS MISTREATED
显示剩余3条评论

4

我认为

var myimage = new PNG('myimage.png');

应该是

var myimage = new PNG.load('myimage.png');

2
是的,这个方法可以工作,但IO操作是同步的。我认为最好的方法是fs.readFile (err, data) -> image = new PNG(data) - Jan Špaček

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接