大家好,很高兴又见面了,我是"高级前端?进阶?",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发,您的支持是我不断创作的动力。
今天给大家带来的主题是前端五大顶级高性能 Node.js 图像开源处理库,话不多说,直接进入正题。
GraphicsMagick 和 ImageMagick
GraphicsMagick 是图像处理领域的瑞士军刀。 它由基础包中的 284K 物理行源代码组成,提供了强大而高效的工具和库集合,支持读取、写入和操作超过 92 种主要格式的图像,包括:重要格式 DPX、GIF、JPEG、JPEG-2000、JXL、PNG、PDF、PNM、TIFF 和 WebP 等格式。
使用 OpenMP 进行多线程图像处理,以便 CPU 密集型任务随着处理器核心的添加而线性扩展。 OpenMP 需要使用 GCC 4.2(或更高版本)进行编译,或使用至少支持 OpenMP 2.0 规范的任何 C 编译器。
GraphicsMagick 具有很强的可移植性,几乎可以在所有 32 位或 64 位 CPU 上运行的通用操作系统下进行编译。 GraphicsMagick 几乎可用于任何 Unix 或类 Unix 系统,包括 Linux。 它还可以在 Windows Vista 及更高版本(Vista、7、8.X、10、11)和 MacOS-X 下运行。
GraphicsMagick 支持巨大的图像,并且已经过十亿像素大小的图像的测试。 GraphicsMagick 可以动态创建新图像,使其适合构建动态 Web 应用程序。 GraphicsMagick 可用于调整图像大小、旋转、锐化、减少颜色或向图像添加特殊效果,并将结果保存为相同或不同的图像格式。 图像处理操作可通过命令行以及 C、C++、Lua、Perl、PHP、Python、Tcl、Ruby、Windows .NET 或 Windows COM 编程接口进行。 经过一些修改,可以使用 ImageMagick 的语言扩展。
GraphicsMagick 最初源自 2002 年 11 月的 ImageMagick 5.5.2,但从那时起就完全独立于 ImageMagick 项目。 自从 ImageMagick 分叉以来,许多作者使用开放开发模型进行了许多改进,但没有破坏 API 或实用程序操作。
以下是相比 ImageMagick 或其他流行软件更喜欢 GraphicsMagick 的一些原因:
- GM 比 ImageMagick 更高效,因此它可以使用更少的资源更快地完成工作。
- GM 比 ImageMagick 更小、更轻(安装空间小 3-5 倍)。
- GM 已被用于处理世界上最大的照片网站(例如 Flickr 和 Etsy)的数十亿个文件。
- GM 不会与其他安装的软件冲突。
- 与 ImageMagick 相比,GM 遇到的安全问题和漏洞更少。
- GM 参与 Google 的 oss-fuzz 项目(自 2018 年 2 月起)。
- GM valgrind 100% 干净(memcheck 和 helgrind)。
- GM 使用 ASan 通过了严格的内存错误测试。
- GM 使用 UBSan 通过了未定义行为测试。
- GM 提供开发者可以信赖的 API 和 ABI 稳定性以及托管版本(ImageMagick 没有),同时提供详细且易于理解的变更日志。
- GM 是免费的,并且可用于支持开放和专有应用程序。
以下是 GraphicsMagick 功能的几个示例:
- 将图像从一种格式转换为另一种格式(例如 TIFF 转换为 JPEG)
- 调整图像大小、旋转、锐化、减少颜色或添加特殊效果
- 创建图像缩略图的蒙太奇
- 创建适合在 Web 上使用的透明图像
- 比较两个图像
- 将一组图像转换为 GIF 动画序列
- 通过组合多个单独的图像来创建合成图像
- 在图像上绘制形状或文本
- 用边框或框架装饰图像
- 描述图像的格式和特征
目前,在 Node.js 中可以通过安装 node-imagemagick 使用,在 Github 上有大约 2k 的 star,值得一试。
jimp
jimp 是完全用 JavaScript 编写的 Node 图像处理库,具有零本机依赖性。jimp 支持的类型也非常丰富,比如:
- @jimp/jpeg
- @jimp/png
- @jimp/bmp
- @jimp/tiff
- @jimp/gif
jimp 提供了以下丰富的方法可以拿来即用:
- blit : 将一个图像传输到另一个图像上。
- blur: 快速模糊图像。
- color : 各种颜色处理方法。
- contain: 将图像包含在一定高度和宽度内。
- cover - 将图像缩放到给定的宽度和高度,保持纵横比。
- displace : 根据置换图置换图像
- dither : 对图像应用抖动效果。
- flip : 沿 x 或 y 轴翻转图像。
- gaussian: 高斯模糊。
- invert :反转图像颜色
- mask: 用一张图像遮盖另一张图像。
- normalize : 标准化图像中的颜色
- print : 将文本打印到图像上
- resize : 调整图像大小。
- rotate : 旋转图像。
- scale : 按一个因子均匀缩放图像。
var Jimp = require("jimp");
// open a file called "lenna.png"
Jimp.read("lenna.png", (err, lenna) => {
if (err) throw err;
lenna
.resize(256, 256) // resize
.quality(60) // set JPEG quality
.greyscale() // set greyscale
.write("lena-small-bw.jpg"); // save
});
一些优质的开源图片处理库,比如: nimp 、 node-vibrant、 lqip 、 webpack-pwa-manifest、wdio-screenshot 、asciify-image、node-sprite-generator 、merge-img 、postcss-resemble-image 、 differencify、 gifwrap、 replace-color 、 handwritten.js 都是基于 jimp。
目前 jimp 在 Github 上通过 MIT 协议开源,有超过 12.9k 的 star、0.8k 的 fork、项目依赖量 434k、NPM 周平均下载量 930k、妥妥的前端优质开源项目。
gm
gm 相当于 Node.js 环境的 GraphicsMagick 和 ImageMagick。
首先需要下载并安装 GraphicsMagick 或 ImageMagick。在 Mac OS X 中,可以简单地使用 Homebrew 并执行以下操作:
brew install imagemagick
brew install graphicsmagick
然后通过 NPM 安装:
npm install gm
通过 subclass gm 以启用 ImageMagick 7+,比如下面的例子:
const fs = require('fs');
const gm = require('gm').subClass({ imageMagick: '7+' });
或者按照如下方式启用 ImageMagick 旧模式(对于 ImageMagick 版本 < 7):
const fs = require('fs');
const gm = require('gm').subClass({ imageMagick: true });
通过使用 GraphicsMagick ,gm 支持将一幅图像合成在另一幅图像之上, 是通过 gm.composite() 公开的。 它的第一个参数是一个图像路径,其中包含对基本图像的更改,以及一个可选的蒙版图像。目前, gm.composite() 仅接受文件路径。
gm('/path/to/image.jpg')
.composite('/path/to/second_image.jpg')
.geometry('+100+150')
.write('/path/to/composite.png', function (err) {
if (!err) console.log('Written composite image.');
});
目前 gm 在 Github 上通过 MIT 协议开源,有超过 6.9k 的 star、0.6k 的 fork、项目依赖量 36k、NPM 周平均下载量 212k、妥妥的前端优质开源项目。
Squoosh
Squoosh 是一款图像压缩 Web 应用程序,可通过多种格式压缩图像大小。
Squoosh 具有以下特征:
- 体积小:较小的图像意味着更快的加载时间, Squoosh 可以压缩文件大小并保持高质量。
- 简单: 打开图像,检查差异,然后立即保存,同时支持调整更小的文件设置。
- 安全:由于 Squoosh 在本地完成所有工作,因此图像永远不会离开您的设备。
虽然 Squoosh 在本地运行,但是 Squoosh 充分利用 Google Analytics 收集以下信息:
- 基本访客数据
- 前后图像尺寸值
- 如果是 Squoosh PWA,收集安装的 Squoosh 类型 。 如果是 Squoosh PWA,则为安装时间和日期。
该库的使用也是非常简单:
import fs from 'fs/promises';
const file = await fs.readFile('./path/to/image.png');
// ingestImage 函数可以接受任何 ArrayBuffer,无论是来自 readFile() 还是 fetch()。
const image = imagePool.ingestImage(file);
但是,值得注意的是,官方宣称该库已经不再维护。
目前 Squoosh 在 Github 上通过 Apache-2.0 协议开源,有超过 19.4k 的 star、1.4k 的 fork、是一个值得关注的前端优秀开源项目。
sharp
sharp 是一个高速的 Node.js 模块,典型用例是将常见格式的大图像转换为较小的、网络友好的不同尺寸的 JPEG、PNG、WebP、GIF 和 AVIF 图像。
由于 sharp 底层使用了 libvips,调整图像大小通常比使用最快的 ImageMagick 和 GraphicsMagick 设置快 4 倍到 5 倍。
sharp 的色彩空间、嵌入式 ICC 配置文件和 Alpha 透明度通道均已正确处理, Lanczos 重采样确保不会为了速度而牺牲质量。除了图像大小调整之外,sharp 还可以进行旋转、提取、合成和伽玛校正等操作。
sharp 在大多数运行 Node.js >= 14.15.0 的现代 macOS、Windows 和 Linux 系统不需要任何额外的安装或运行时依赖项。
sharp 的使用也非常简单,比如下面的示例:
const sharp = require('sharp');
sharp(inputBuffer)
.resize(320, 240)
.toFile('output.webp', (err, info) => { ... });
// callback模式
sharp('input.jpg')
.rotate()
.resize(200)
.jpeg({ mozjpeg: true })
.toBuffer()
.then( data => { ... })
.catch( err => { ... });
// promise模式
const semiTransparentRedPng = await sharp({
create: {
width: 48,
height: 48,
channels: 4,
background: { r: 255, g: 0, b: 0, alpha: 0.5 }
}
})
.png()
.toBuffer();
// async await
目前 sharp 在 Github 上通过 Apache-2.0 协议开源,有超过 26.1k 的 star、1.3k 的 fork、项目依赖量 546k、NPM 周平均下载量 2674k、妥妥的前端优秀开源项目。
不同处理库的比较
JPEG
解压缩 2725x2225 JPEG 图像,使用 Lanczos 3 重采样(如果可用)将大小调整为 720x588,然后以 quality 设置 80 压缩 JPEG。
注意:jimp 不支持 Lanczos 3,而是使用双三次重采样。
不同库的输出数据如下:
从压缩速度来看,sharp 是最快的,其次是 imagemagick、gm、squoosh-lib、jimp 等。
PNG
解压缩 2048x1536 RGBA PNG 图像,预乘 Alpha 通道,使用 Lanczos 3 重采样(如果可用)将大小调整为 720x540,取消预乘,然后使用“默认”zlib 压缩级别 6 压缩为 PNG,并且不使用自适应过滤。
注意:jimp 不支持预乘/取消预乘。
不同库的输出数据如下:
从压缩速度来看与 JPEG 类似,sharp 是最快的、其次是 imagemagick、jimp、gm 、squoosh-lib 等。
本文总结
本文主要和大家介绍前端五大顶级高性能 Node.js 图像开源库,包括:jimp、gm、GraphicsMagick 和 ImageMagick、Squoosh、sharp。
因为篇幅有限,文章并没有过多展开,如果有兴趣,可以在我的主页继续阅读,同时文末的参考资料提供了大量优秀文档以供学习。最后,欢迎大家点赞、评论、转发、收藏!
参考资料
https://github.com/jimp-dev/jimp
http://www.graphicsmagick.org/
https://imagemagick.org/index.php
https://imagemagick.en.softonic.com/mac
https://github.com/rsms/node-imagemagick
https://www.droidviews.com/manipulate-images-android-graphicsmagick/
https://squoosh.app/
https://github.com/GoogleChromeLabs/squoosh
https://www.npmjs.com/package/@squoosh/lib
https://blogaid.net/why-squoosh-is-my-image-optimization-tool-of-choice/
https://github.com/lovell/sharp
https://github.com/FFmpeg/FFmpeg
https://sharp.pixelplumbing.com/performance
https://dev.to/gulshansaini/how-to-crop-image-in-browser-using-jimp-2l22