Node.js:不使用 ImageMagick 调整图像大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24026320/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Node.js: image resizing without ImageMagick
提问by zacr0
I'm developing a web app on Node.js (+ express 4) where users can set their profile image by uploading it to the server. We already limit the file mimetype and max filesize, so the user can't upload more than 200KB png or jpeg images.
我正在 Node.js (+ express 4) 上开发一个 web 应用程序,用户可以通过将其上传到服务器来设置他们的个人资料图片。我们已经限制了文件 mimetype 和最大文件大小,因此用户不能上传超过 200KB 的 png 或 jpeg 图像。
The problem is we'd like to resize (serverside) the uploaded image resolution to 200x200 to improve page loading and saving space on disk. After some research, all answers pointed to using any module based on ImageMagick or GraphicsMagick.
问题是我们想将(服务器端)上传的图像分辨率调整为 200x200,以改善页面加载并节省磁盘空间。经过一番研究,所有答案都指向使用基于 ImageMagick 或 GraphicsMagick 的任何模块。
However, having to install ImageMagick/GraphicsMagick to do a simple image resizing seems too overkill for me, so, is there any other solution other than this for Node.js?
然而,必须安装 ImageMagick/GraphicsMagick 来做一个简单的图像大小调整对我来说似乎太过分了,所以,对于 Node.js,除了这个还有其他解决方案吗?
Edit:I've changed the accepted solution to sharpas the previous solution (lwip) is no longer maintained. Thanks for all your feedback!
编辑:由于不再维护以前的解决方案 (lwip),我已将接受的解决方案更改为尖锐。感谢您的所有反馈!
回答by jcupitt
I would vote for sharp:
我会投票给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
});
It's fast, typically 6x faster than the fastest imagemagick-based node bindings, and runs in very little memory, perhaps 10x less. sharp links to the libvipsimage library directly, there is no shelling out to an external program, and the library itself is faster and more efficient than *magick at this task. It supports useful things like stream, buffer and filesystem input and output, colour management, transparency, promises, overlays, WebP, SVG, and more.
它很快,通常比最快的基于 imagemagick 的节点绑定快6 倍,并且运行时内存很少,可能少 10 倍。直接指向 libvips图像库的清晰链接,无需对外部程序进行炮击,并且库本身在此任务上比 *magick 更快、更高效。它支持有用的东西,如流、缓冲区和文件系统输入和输出、颜色管理、透明度、承诺、叠加、WebP、SVG 等。
As of sharp 0.20, npm will automatically download complete pre-compiled binaries on most platforms, so there's no need for node-gyp. Just enter:
从 0.20 开始,npm 将在大多数平台上自动下载完整的预编译二进制文件,因此不需要 node-gyp。只需输入:
npm install sharp
or:
或者:
yarn add sharp
And off you go.
你走吧。
回答by EyalAr
I have recently started developing an image processing module for NodeJS without any runtime dependencies (read why). It's still at early stages, but already usable.
我最近开始为 NodeJS 开发一个图像处理模块,没有任何运行时依赖(阅读原因)。它仍处于早期阶段,但已经可用。
What you are asking for would be done as follows:
您要求的操作如下:
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.
});
});
More info at the module's Github repo.
模块的Github repo 中的更多信息。
回答by Arvind
Take a look at lwip : https://github.com/EyalAr/lwip
看看 lwip :https: //github.com/EyalAr/lwip
Very simple and easy to use
非常简单易用
npm install lwip
and then in your node code,
然后在您的节点代码中,
// 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.
});
});
I have successfully implemented this in my file uploaderand it works like a charm.
我已经在我的文件上传器中成功实现了这一点,它就像一个魅力。
回答by edtech
There is a good image manipulation library written entirely in JavaScript, without dependencies to any other libraries, Jimp. https://github.com/oliver-moran/jimp
有一个很好的图像处理库,完全用 JavaScript 编写,不依赖任何其他库,Jimp。https://github.com/oliver-moran/jimp
Example usage:
用法示例:
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
});
回答by Ry-
sharphas enjoyed some popularity recently, but it's the same idea as *Magick bindings.
夏普最近很受欢迎,但它与 *Magick 绑定的想法相同。
However, having to install ImageMagick/GraphicsMagick to do a simple image resizing seems too overkill for me
然而,必须安装 ImageMagick/GraphicsMagick 来做一个简单的图像大小调整对我来说似乎太过分了
Image resizing is anything but simple. The JPEG format is particularly complex, and there are several ways to scale graphics with results of varying quality, few of them easily implemented. Image processing libraries exist to do this job, so if there's no other reason why you can't install them, go for it.
图像大小调整绝非易事。JPEG 格式特别复杂,有多种方法可以缩放具有不同质量结果的图形,但很少有方法可以轻松实现。图像处理库的存在就是为了完成这项工作,所以如果没有其他原因无法安装它们,那就去做吧。
回答by Dimitry Ivanov
Canvas is 2.3 times fasterthan ImageMagic.
Canvas比 ImageMagic快 2.3 倍。
You can try to compare Node.js modules for images manipulation - https://github.com/ivanoff/images-manipulation-performance
您可以尝试比较用于图像处理的 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
回答by Andrei Volgin
If you don't need a large image, you can resize it on the client side before uploading it:
如果你不需要大图片,你可以在上传之前在客户端调整它的大小:
Reading files in JavaScript using the File APIs
Image resizing client-side with javascript before upload to the server
在上传到服务器之前使用 javascript 在客户端调整图像大小
Many users might have a good picture of themselves from a smartphone, and many of them are over 200kB. Note that client-provided data is not to be trusted, so server-side checks still apply.
许多用户可能通过智能手机对自己有一个很好的了解,其中许多都超过 200kB。请注意,客户端提供的数据是不可信的,因此服务器端检查仍然适用。
回答by Dan Caseley
I was using lwip (as previously suggested by arvind) but switched to png-crop. It seems to work a little faster for me (Win 8.1 x64, Node v0.12.7). The code in the repo looks incredibly lightweight, and operationally it's simple to use.
我正在使用 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);
Of course, it'll only do png files...
当然,它只会做 png 文件......
回答by Alex Seceleanu
Sharp work very well and is easy to use with streams, work like a charm, but you need to compile it with the node version, this is a downside to it. I was using Sharp for image processing, with an image from an AWS S3 bucket and worked perfectly, but I had to use another module. GM didn't work for me, but Jimp worked very good!
Sharp 工作得很好,并且很容易与流一起使用,就像一个魅力一样,但是你需要用 node 版本编译它,这是它的一个缺点。我使用 Sharp 进行图像处理,使用来自 AWS S3 存储桶的图像并且运行良好,但我不得不使用另一个模块。GM 对我不起作用,但 Jimp 工作得很好!
You have to pay attention to the path of the written picture, it might give you some errors if you start the path with a "/".
你要注意写入图片的路径,如果路径以“/”开头,可能会给你一些错误。
This is how I used Jimp in nodeJS:
这就是我在 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() } }
});
Also watch out for the order of execution, put a callback so other things don't happen when you don't want to. Tried using "await" for the Jimp.read() but it didn't do the job well.
还要注意执行顺序,放置回调,以便在您不想时不会发生其他事情。尝试对 Jimp.read() 使用“await”,但效果不佳。
回答by Nouman Dilshad
You can do this using jimp (node_module)
您可以使用 jimp (node_module) 执行此操作
Local Write:
本地写入:
Jimp.read(path) // this can be url or local location
.then(image=> {
image
.resize(size, Jimp.AUTO) // jimp.AUTO automatically sets the width so that the image doesnot looks odd
.write('path-to-save');
})
.catch(err => {
console.log(err);
});
To upload to s3 or where ever you like.
上传到 s3 或任何你喜欢的地方。
Jimp.read(urls) // this can be url or local location
.then(image=> {
image
.resize(size, Jimp.AUTO) // jimp.AUTO automatically sets the width so that the image doesnot looks odd
.getBase64(Jimp.AUTO, (err, res) => {
const buf = new Buffer(
res.replace(/^data:image\/\w+;base64,/, ""),
"base64"
);
var data = {
Key: key,
Bucket: bucket,
Body: body,
ContentEncoding: "base64",
ContentType: "image/jpeg"
};
s3.putObject(data, function(err, data) {
if (err) {
throw err;
} else {
console.log("succesfully uploaded the image!");
}
});
});
})
.catch(err => {
console.log(err);
});

