纯JavaScript图像处理

17

我有一个使用案例,想要创建(a)一个Node应用程序,该程序(b)执行基本的图像操作(PNG裁剪和调整大小),但是(c)我不能使用外部依赖项,如本机库、GraphicsMagick、ImageMagick、PhantonJS、Inkscape等。

一切都必须在纯JavaScript中完成。

考虑到我想要进行的操作非常简单(只是PNG裁剪和调整大小),这似乎并不难。然而,我找不到没有最终具有外部或本机依赖项的裁剪/调整大小库。

是否存在真正的纯JavaScript库可用于裁剪/调整大小?如果我不得不自己实现它,那么实现这个的难度会有多大?以及我应该从哪里开始?

或者,是否有适合此目的的C函数可以使用emscripten编译?


在纯Javascript中处理PNG是“可能的”——如果您对“可能”的广泛解释慷慨的话。Javascript可以轻松地操作二进制文件;解压缩然后重新压缩原始图像数据并不那么容易(这需要一个纯JS版本的Flate和Deflate),但仍然在“可行”的范围内。然而,我认为它不会很快。 - Jongware
1
@Jongware,谢谢。速度不是必要的要求。唯一的限制是我不能依赖于任何本地依赖项。 - Oliver Moran
@LcSalazar,谢谢。该应用程序是一个命令行实用程序。它将手动定期运行。因此,我不太关心速度。图像处理部分只是其中的一小部分 - 也是“好有”的一部分。因此,如果不可能,我不会放弃Node。但是,我想避免任何二进制文件和外部依赖。将图像上传到服务器以进行裁剪和调整大小将成为外部依赖。 - Oliver Moran
2
对于JPG文件,jpg-js非常适用。对于PNG文件,可以尝试使用node-png。以后参考的话,npmjs.org是你的好朋友,你应该尝试搜索到的库 =) - Mike 'Pomax' Kamermans
显示剩余3条评论
3个回答

56

好的,最终我自己开发了一个工具,并已发布在NPM上,链接在这里:https://www.npmjs.org/package/jimp

使用示例如下:

var Jimp = require("jimp");

var lenna = new Jimp("lenna.png", function () {
    this.crop(100, 100, 300, 200) // crop
        .resize(220, 220) // resize
        .write("lenna-small-cropped.png"); // save
});

突破点在于在此处找到了一个JavaScript双立方二次缩放算法:https://github.com/grantgalitz/JS-Image-Resizer

感谢Mike 'Pomax' Kamermans指出正确的方向,以及Grant Galitz提供的令人惊叹的缩放算法。


谢谢你,我很惊讶这上面反馈很少。我不得不稍微修改一下,以便直接使用缓冲区,并且它绝对非常适合小操作。干得好! - Igor R
1
@IgorR,谢谢。如果您有任何改进,请打开问题或发起拉取请求:https://github.com/oliver-moran/jimp - Oliver Moran
1
我所做的是不完整的,只能用于jpg,这是一个肮脏的实现,不足以进行拉取,只是为了我的目的而使其工作。当我有时间时,将尝试完成它并改进代码,然后发起拉取请求。 我只是想知道大多数人如何能够忍受*Magicks的负担,而完全可以不用它。 - Igor R
1
我现在已经使用Jimp几个月了。 我将其用作从sharp回退(因为sharp速度更快,但往往无法安装)。 话虽如此,向@OliverMoran致敬,做得好! 它完全符合宣传:无需依赖项且运行良好。 - cmroanirgo
@OliverMoran 我想将彩色图像转换为纯黑白(不是灰度)。我正在尝试使用你的宝石,但无法找到正确的选项。我正在尝试使用RGB值。如果您能指导我正确的方向,那就太好了。Jimp.read(input_file, function (err, lenna) { if (err) throw err; lenna.color([ { apply: 'red', params: [ -256 ] }, { apply: 'green', params: [ -256 ] }, { apply: 'blue', params: [ -256 ] }, ]);
lenna.write(output_file); });
- Xeeshan
显示剩余3条评论

2
你可以尝试比较Node.js中的图像处理模块 - https://github.com/ivanoff/images-manipulation-performance
author's results:
  sharp.js : 9.501 img/sec; done in 10.525585 sec;
  canvas.js : 8.246 img/sec; done in 12.12766 sec;
  gm.js : 4.433 img/sec; done in 22.557112 sec;
  gm-imagemagic.js : 3.654 img/sec;
  lwip.js : 1.203 img/sec;
  jimp.js : 0.445 img/sec;

我不知道为什么这个被踩了,但我觉得上面的链接非常有用。 - John James

1

使用MarvinJ进行纯JavaScript图像操作的缩放和裁剪示例:

var canvas1 = document.getElementById("canvas1");
var canvas2 = document.getElementById("canvas2");
var canvas3 = document.getElementById("canvas3");

image = new MarvinImage();
image.load("https://i.imgur.com/gaW8OeL.jpg", imageLoaded);

function imageLoaded(){
  imageOut = image.clone()
  image.draw(canvas1) 
  // Crop
  Marvin.crop(image, imageOut, 50, 50, 100, 100);
  imageOut.draw(canvas2);
  // Scale
  Marvin.scale(image, imageOut, 100);
 imageOut.draw(canvas3); 
}
<script src="https://www.marvinj.org/releases/marvinj-0.7.js"></script>
<canvas id="canvas1" width="200" height="200"></canvas>
<canvas id="canvas2" width="200" height="200"></canvas><br/>
<canvas id="canvas3" width="200" height="200"></canvas>


你可以使用node-canvas来完成这个任务,然后将其保存到文件中。我正在尝试在Node中使用MarvinJ,但遇到了一些困难。 - jusopi

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