使用 sharp 实现图片转换
为什么是 sharp?
最近在升级 coderyuan-image-server 这个图片服务的项目,主要是想增加对 AVIF、HEIC 图片格式的支持,于是就想找找新的方案。
以前的方案是使用 GraphicsMagick 或者 ImageMagick 来进行图片的转换,但是这两个库对于 HEIC 和 AVIF 这样的编码格式支持的并不好,所以必须要放弃它们了。
偶然间发现 sharp 这个库,从它官方的介绍中看,貌似 API 更简单,而且支持的格式也更多,性能更好,所以就选择它作为图片转换的实现方案了。
先介绍一下 sharp 和它背后的 libvips
简单来说 sharp 是基于 libvips 的 Node.js 图片处理实现,根据 libvips 官方的说明,libvips 具有速度快、占用内存少、支持格式多的特点(具体工作原理参见:https://www.libvips.org/API/current/How-it-works.html),非常适合做静态图片的转换工作,能够在各方面超越传统的 GrapicsMagick 和 ImageMagick。
基于 libvips 出色的性能和丰富的格式支持,也诞生了众多语言的封装,主流的 Java、Python、Go 等语言都有对应的实现,也有一系列基于 libvips 能力扩展的图片处理工具库,sharp 就是其中之一,也几乎是 JavaScript 环境下唯一可用的 libvips 实现。
sharp 底层其实也是 Node C++ 实现的,可以通过在 npm install 后编译 Native 代码,实现多个平台的图片处理功能。
存在的问题
此次升级 coderyuan-image-server 的主要需求是支持 AVIF 和 HEIC 格式的图片,而 sharp 的文档中说明了,sharp 默认使用的 libvips 无法支持真正以 HEVC 编码的图片格式,默认只能以 AV1 编码存储。如果在转换时使用如下代码:
1 | sharp().heif({ |
则会收到如下错误:
1 | /home/yuanguozheng/github/image-utils/node_modules/sharp/lib/output.js:1443 |