Node.js:不使用ImageMagick调整图像大小

问题描述 投票:65回答:9

我正在Node.js(+ express 4)上开发一个Web应用程序,用户可以通过将其上传到服务器来设置他们的个人资料图像。我们已经限制了文件mimetype和max filesize,因此用户无法上传超过200KB的png或jpeg图像。

问题是我们希望将上传的图像分辨率调整为(服务器端)为200x200以改善页面加载并节省磁盘空间。经过一些研究,所有答案都指向使用基于ImageMagick或GraphicsMagick的任何模块。

但是,必须安装ImageMagick / GraphicsMagick进行简单的图像调整大小对我来说似乎太过分了,所以,Node.js还有除此之外的其他解决方案吗?

编辑:我已将已接受的解决方案更改为sharp,因为之前的解决方案(lwip)已不再维护。感谢您的所有反馈!

image node.js image-resizing
9个回答
74
投票

我会投票给sharp

sharp('input.jpg')
  .resize(200, 200)
  .toFile('ouput.jpg', function(err) {
    // output.jpg is a 200 pixels wide and 200 pixels high image
    // containing a scaled and cropped version of input.jpg
  });

它很快,typically 6x faster than the fastest imagemagick-based node bindings,并且运行在很少的记忆中,perhaps 10x less。直接链接到libvips图像库,没有外部程序的炮轰,并且库本身比* magick在此任务更快,更有效。它支持流,缓冲和文件系统输入和输出,颜色管理,透明度,承诺,叠加,WebP,SVG等有用的东西。

截至0.20,npm将在大多数平台上自动下载完整的预编译二进制文件,因此不需要node-gyp。只需输入:

npm install sharp

要么:

yarn add sharp

你离开了。


70
投票

我最近开始为NodeJS开发一个没有任何运行时依赖性的图像处理模块(read why)。它还处于早期阶段,但已经可以使用了。

您要求的内容如下:

image.resize(200, 200, function(err, image){
    // encode resized image to jpeg and get a Buffer object
    image.toBuffer('jpg', function(err, buffer){
        // save buffer to disk / send over network / etc.
    });
});

更多信息在模块的Github repo


16
投票

看看lwip:https://github.com/EyalAr/lwip

非常简单易用

npm install lwip

然后在你的节点代码中

// obtain an image object:
require('lwip').open('image.jpg', function(err, image){

  // check err...
  // define a batch of manipulations and save to disk as JPEG:
  image.batch()
    .scale(0.75)          // scale to 75%
    .rotate(45, 'white')  // rotate 45degs clockwise (white fill)
    .crop(200)            // crop a 200X200 square from center
    .blur(5)              // Gaussian blur with SD=5
    .writeFile('output.jpg', function(err){
      // check err...
      // done.
    });

});

我已经在我的file uploader中成功实现了它,它就像一个魅力。


10
投票

有一个很好的图像处理库完全用JavaScript编写,没有依赖于任何其他库,Jimp。 https://github.com/oliver-moran/jimp

用法示例:

var Jimp = require("jimp");

// open a file called "lenna.png"
Jimp.read("lenna.png", function (err, lenna) {
    if (err) throw err;
    lenna.resize(256, 256)            // resize
         .quality(60)                 // set JPEG quality
         .write("lena-small.jpg"); // save
});

8
投票

sharp最近享受了一些人气,但它与* Magick绑定的想法相同。

但是,必须安装ImageMagick / GraphicsMagick进行简单的图像调整大小对我来说似乎太过分了

图像大小调整绝非易事。 JPEG格式特别复杂,有几种方法可以使用不同质量的结果来缩放图形,很少有这些方法可以轻松实现。存在图像处理库来完成这项工作,所以如果没有其他原因你无法安装它们,那就去做吧。


5
投票

Canvas比ImageMagick快2.3倍。

您可以尝试比较Node.js模块以进行图像处理 - https://github.com/ivanoff/images-manipulation-performance

author's results:
 sharp.js : 9.501 img/sec; minFreeMem: 929Mb
 canvas.js : 8.246 img/sec; minFreeMem: 578Mb
 gm.js : 4.433 img/sec; minFreeMem: 791Mb
 gm-imagemagic.js : 3.654 img/sec; minFreeMem: 804Mb
 lwip.js : 1.203 img/sec; minFreeMem: 54Mb
 jimp.js : 0.445 img/sec; minFreeMem: 82Mb

3
投票

如果您不需要大图像,可以在上传之前在客户端调整大小:

Reading files in JavaScript using the File APIs

Image resizing client-side with javascript before upload to the server

许多用户可能从智能手机上看到自己的好照片,其中许多用户超过200kB。请注意,客户端提供的数据不受信任,因此服务器端检查仍然适用。


1
投票

我正在使用lwip(如先前arvind所建议的那样)但是切换到了png-crop。对我来说似乎工作得快一点(Win 8.1 x64,Node v0.12.7)。 repo中的代码看起来非常轻巧,操作起来很简单。

var pngcrop = require('png-crop');
var config = {left: 10, top: 100, height: 150, width: 150};
pngcrop.crop('cats.png','cats-cropped.png',config);

当然,它只会做png文件......


0
投票

锐利的工作非常好,易于使用流,工作就像一个魅力,但你需要用节点版本编译它,这是一个缺点。我使用Sharp进行图像处理,使用来自AWS S3存储桶的图像并且工作得很好,但我不得不使用另一个模块。通用汽车不适合我,但是Jimp工作得非常好!

你必须注意书面图片的路径,如果你用“/”开始路径,它可能会给你一些错误。

这是我在nodeJS中使用Jimp的方式:

const imageUrl = `SOME_URL`;
let imgExported = 'EXPORTED_PIC.png';

Jimp.read(imageUrl)
    .then(image => {
        image   
            .resize(X, Y) 
            .write(`tmp/`+ imgExported, err => { 
                if(err) 
                    console.error('Write error: ', err);
                else { ... // don't forget to put a callback() } }

            });

还要注意执行的顺序,进行回调,以便在您不想要时不会发生其他事情。尝试使用“等待”为Jimp.read(),但它没有做好这项工作。

© www.soinside.com 2019 - 2024. All rights reserved.