前言
本文的主要内容是在 Rocky Linux/AlmaLinux 下通过源代码编译安装 libwebp。
WebP 是一款最早由谷歌公司开发的现代图像格式,是一种规范,这种格式比传统的图片压缩格式效率更高、压缩效果更好,同时还支持透明和动画,以及提供有损和无损压缩的选项。
而 libwebp 实现了该格式编解码和其他功能特性的软件库,包含有编解码器、格式转换工具、用于编程和开发的动态库与库代码以及 cwebp、gif2webp 等命令行工具。
虽然通过安装包或者系统软件源也可以安装,但是为了定制选项,尤其是使用比 libjpeg 更优秀替代品的 libjpeg-turbo,所以选择编译安装。
当其他图像格式转换成 WebP,在保持图片清晰度的情况下,体积将大大地减小;在计算网络流量的服务器环境下将会得到很好的优化,能够很大程度上削减带宽和流量成本,同时优化服务器的访问性能。
结合简单的配置,HTTP 服务器可自适应返回 WebP 格式的图片文件,本文就以 Nginx 为例。
什么是 libwebp
libwebp 是一套集合 WebP 实用应用程序的库,安装了它可得到若干可对图片进行操作的工具,如:
- libwebp:可编程的动态库,用于使用编程语言进行编码或解码。
- cwebp:编码器。可对其他如PNG、JPEG等格式的图片转换为 WebP 格式。
- dwebp:解码器。解码为PNG等格式,但不能解码动图。
- vwebp:WebP 文件查看器,但它在下文编译安装时不被包括在其中。
- webpmux:多路复用工具。
webpmux – 从非动画形式的 WebP 图片创建动画文件,也可从动画图片中提取帧。
-
gif2webp:用于转换 GIF 的工具。
以上参考:
https://developers.google.com/speed/webp/download?hl=zh-cn 。
https://developers.google.com/speed/webp/docs/webpmux?hl=zh-cn
WebP 的完整安装过程
在此过程中需要安装基本依赖,为支持 JPEG、PNG 和 GIF,根据操作系统分别安装最新的 libjpeg-turbo、libpng 和 libgif。
由于之前已经发布过 Rocky Linux/AlmaLinux 编译安装 libjpeg-turbo 的文章 《Linux编译libjpeg-turbo》,在此使用该安装成果即可,可以说这个是本文的依赖之一,当然您也可以选择其他 libjpeg 或 libjpeg-turbo 安装源,不过要修改 WebP 的编译选项。
尽管在使用系统软件源安装基本依赖时会安装旧版本的 libwebp,这没关系,我们可以重新编译,并把编译后的目录和文件放到一个指定的(目录)位置,保证不与旧版本 libwebp 冲突。未来编译 libgd 时这有大用。
步骤一:编译的基本依赖
安装的基本依赖有 wget、gcc、make 等涉及到依赖文件下载工具、c/c++ 编译器、编译构建安装工具。
二:安装 giflib 和 libpng
最好安装最新版本的 libgif 和 libpng。
在网站 https://pkgs.org/ 可以找到几乎所有主流 Linux 发行版所支持的软件安装包文件。
其中:
- libxxx/xxxlib-版本号:用于操作图像格式文件的函数库
- xxx-devel:安装包包含开发编译的代码和动态库文件。
- xxx-utils/xxx-tools:包含二进制命令行工具,用于图像之间的格式转换,或者其他用途。
要注意的是必须下载与服务器相同硬件平台的安装包,比如 x86_64、aarch64 等。
查看硬件平台:
lscpu | grep -i 'Architecture:'
giflib 安装包
可以于 https://pkgs.org/search/?q=giflib 为不同的操作系统下载相应的安装包。
安装包:giflib、giflib-devel 和 giflib-utils。
libpng 安装包
到 https://pkgs.org/search/?q=libpng 下载相应操作系统的 libpng 安装包。
安装包:libpng、libpng-tools、libpng-devel 和 libpng-static。
三:下载和解压 libwebp 源码包
到 https://storage.googleapis.com/downloads.webmproject.org/releases/webp/index.html 下载最新 libwebp 源码包。
由于其提供的是 .tar.gz 压缩包,所以或者要先安装 tar 命令来解压缩(可能系统已经集成该命令):
dnf install -y tar
四:配置软件源码
执行 libwebp 源码根目录的 ./configure 命令检查系统环境和依赖库,并且根据该命令指定的用户选项生成 Makefile 文件,比如指定安装目录和指定已安装的 jpeg 目录(可以是 libjpeg-turbo 相关目录)等。
这里指定安装目录为 /usr/local/libwebp。
五:编译和安装
如果《步骤四》成功执行,那么就可以进行这一个步骤,若是失败的话,请按提示检查和修复哪里出了错。
六:设置环境变量
这一步设置 PATH 和 LD_LIBRARY_PATH 两个环境变量。
相信环境变量 PATH 大家都不陌生,这里不展开说,就说说 LD_LIBRARY_PATH 吧。
LD_LIBRARY_PATH 指定系统加载 .so 动态链接库文件时优先搜索的目录(全路径),它还优先于 /etc/ld.so.conf 文件内指定的路径们。
并且把此变量放置于 /etc/profile 文件中,且用 export 来将变量添加到当前 Shell 会话中。
这里将 WebP 安装目录下 lib 目录的完整路径添加到 LD_LIBRARY_PATH 环境变量中。
七:把 lib 目录放到 ld.so.conf 文件中
/etc/ld.so.conf 文件用于指定共享库的搜索路径,以便动态链接器可以正确地加载共享库。
系统在寻找动态库时,该文件还在
LD_LIBRARY_PATH之后寻找。
把 libwebp 安装目录下的 lib 目录全路径放到 ld.so.conf 文件中。
八:检查 libwebp 动态库的路径和文件名
在 libwebp 安装完成后,可检查它的动态库是否已经在寻找路径中且正确安装。
执行:
ldconfig -v | grep webp
完整的自动化安装脚本
下方的链接中有安装脚本:
https://paste.ubuntu.com/p/wNzYntqnPB/
复制粘贴脚本到服务器的终端下,如遇到链接失效的情况,请及时联系笔者(通过微信公众号或者电子邮箱)。
执行上述自动化脚本:
bash /tmp/installer.sh
rm -f /tmp/installer.sh
验证动态库版本
readelf -d /usr/local/libwebp/lib/libwebp.so
[root@localhost ~]# readelf -d /usr/local/libwebp/lib/libwebp.so
Dynamic section at offset 0x6dd80 contains 28 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libsharpyuv.so.0]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000e (SONAME) Library soname: [libwebp.so.7]
0x000000000000000f (RPATH) Library rpath: [/usr/local/libwebp/lib]
0x000000000000000c (INIT) 0x3000
0x000000000000000d (FINI) 0x59314
0x0000000000000019 (INIT_ARRAY) 0x6dab0
0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
配置 Nginx WebP 自适应
所谓 WebP 自适应,就是服务器如果接收到以 png、jpeg、jpg 或 gif 为后缀的文件 URL 请求,并且服务器上存在类似于 png.webp、jpg.webp 等扩展名的文件,那么将以相应 .webp 的文件内容响应回到客户端,此过程是智能和自动的。
比如请求 https://xxxxxx.com/images/xxx.jpg,倘若 images/ 目录下存在一个名为 xxx.jpg.webp 的文件,那么将响应返回后者。若直接请求 https://xxxxxx.com/images2/xxxxxxx.webp 这样以 .webp 为扩展名的文件,将直接响应该文件。
本文以 Nginx 作为服务器软件为例子。
http {
# 在 http 块中设置
# 其他配置...
## WebP支持
map $arg_no_webp $no_webp{
default "";
"1" "no_webp";
}
map $http_accept $webp_suffix{
default "";
"~*webp" ".webp";
}
server {
# 在 server 块中设置
# 其他配置...
location ~* ^/.+\.(png|jpe?g|gif)$ {
add_header Vary Accept;
try_files $uri$webp_suffix$no_webp $uri =404;
}
# 若是有类似于下方的配置,则按以下的配置设置
# 如果没有,则仅须上面的配置即可
location @test-prefix {
rewrite /test-prefix/(.*)$ /test-prefix/index.php?/$1 last;
}
location ^~ /test-prefix {
alias /var/www/site/site-root/;
## try_files $uri $uri/ @cxzl-test;
try_files $uri$webp_suffix$no_webp $uri $uri/ @test-prefix;
location ~ \.php$ {
fastcgi_pass php;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $request_filename;
include fastcgi_params;
# ...
}
# ...
}
# 其他配置...
}
# 其他配置...
}
测试
# 将一张 JPEG 图片 test-origin.jpg 转换为 WebP 文件:
cwebp test-origin.jpg -o test.webp
转换好后把得到的test.webp文件下载到有桌面的电脑上查看是否已经转换成功。
用图形界面图像软件ImageMagick查看到此图片文件的格式是 WebP。
后记
本文展示了 libwebp 通过源代码编译安装的全过程,过程中还安装了 libgif 和 libpng 相关的动态库,以解决编译依赖。
在众多的 Linux 发行版中,之所以选择 Rocky Linux 和 AlmaLinux 来演示这个编译过程,因为两者皆是 RHEL 一比一二进制兼容的操作系统;尽管两者有略微的不同,但是它们最具典型。而且 RHEL 及其衍生发行版在 Linux 服务器操作系统中的市场份额最高。
虽然在安装依赖过程中已经有 libwebp 安装在服务器上,但是依然可以在以后的编译中再有用到 libwebp 的地方指定本文 WebP 的安装路径和
lib、include两个目录的路径。
此外,本文还说明了如何配置 Nginx WebP 自适应。
鉴于本人的相关知识储备以及能力有限,本博客的观点和描述如有错漏或是有考虑不周到的地方还请多多包涵,欢迎互相探讨,一起学习,共同进步。
本文章可以转载,但是需要说明来源出处!
本文使用的部分图片来源于网上,若是侵权,请与本文作者联系删除: admin@icxzl.com



