我正在Node.js(+ express 4)上开发一个Web应用程序,用户可以通过将其上传到服务器来设置他们的个人资料图像。我们已经限制了文件mimetype和max filesize,因此用户无法上传超过200KB的png或jpeg图像。
问题是我们希望将上传的图像分辨率调整为(服务器端)为200x200以改善页面加载并节省磁盘空间。经过一些研究,所有答案都指向使用基于ImageMagick或GraphicsMagick的任何模块。
但是,必须安装ImageMagick / GraphicsMagick进行简单的图像调整大小对我来说似乎太过分了,所以除了Node.js之外还有其他解决方案吗?
修改:我已将已接受的解决方案更改为sharp,因为之前的解决方案(lwip)已不再维护。感谢您的所有反馈!
答案 0 :(得分: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的更多信息。
答案 1 :(得分:65)
我会投票给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
然后离开。
答案 2 :(得分: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中成功实现了它,它就像一个魅力。
答案 3 :(得分: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
});
答案 4 :(得分:8)
sharp最近很受欢迎,但它与* Magick绑定的想法相同。
但是,不得不安装ImageMagick / GraphicsMagick进行简单的图像调整大小对我来说太过分了
图像大小调整绝非易事。 JPEG格式特别复杂,有几种方法可以使用不同质量的结果来缩放图形,很少有这些方法可以轻松实现。存在图像处理库来完成这项工作,所以如果你没有其他原因无法安装它们,那就去吧。
答案 5 :(得分:5)
Canvas 比ImageMagic快 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
答案 6 :(得分:3)
如果您不需要大图片,可以在上传之前在客户端调整大小:
Reading files in JavaScript using the File APIs
Image resizing client-side with javascript before upload to the server
许多用户可能从智能手机上看到自己的好照片,其中许多用户超过200kB。请注意,客户端提供的数据不受信任,因此服务器端检查仍然适用。
答案 7 :(得分:0)
Sharp可以很好地工作,并且易于在流中使用,就像魅力一样工作,但是您需要使用节点版本进行编译,这是它的缺点。 我使用Sharp进行图像处理,并使用了AWS S3存储桶中的图像,并且运行良好,但是我不得不使用另一个模块。通用汽车没有为我工作,但吉普却表现出色!
您必须注意所写图片的路径,如果以“ /”开头的路径可能会给您带来一些错误。
这就是我在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()使用“等待”,但效果不佳。
答案 8 :(得分:0)
您可以使用jimp(node_module)
本地写入:
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);
});
要上传到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);
});
答案 9 :(得分:0)
我喜欢resize-img库,因为它很简单。
const fs = require('fs');
const resizeImg = require('resize-img');
(async () => {
const image = fs.readFileSync('unicorn.png');
const newImage = await resizeImg(image, { width: 128, height: 128 });
fs.writeFileSync('unicorn-128x128.png', newImage);
})();
答案 10 :(得分:0)
使用Google Drive API v3调整图像大小。建议Google Apps脚本使用此方法将图像插入Google表格中。
算法:
并注意GDrive配额: