WebP Server部署手册
WebP-Server工具,可将JPG/PNG即时压缩为WebP格式,可以大幅度的减少图片体积,减少出口带宽,提高用户体验。目前支持的图片格式:JPEG、PNG、BMP、GIF。
WebP
WebP是由Google推出的一种全新图片文件格式,也是Telegram Stickers主力使用的文件格式,可为Web上的图像提供卓越的压缩,它是在保证原有的图像质量前提下尽可能减少图形体积的一种格式,从而使Web加载性能的提升更快。
- WebP的有损压缩算法是基于VP8视频格式的帧内编码,并以RIFF作为容器格式。 因此,它是一个具有八位色彩深度和以1:2的比例进行色度子采样的亮度-色度模型(YCbCr 4:2:0)的基于块的转换方案。不含内容的情况下,RIFF容器要求只需20字节的开销,依然能保存额外的元数据(metadata)。
- WebP图像的边长限制为16383像素。
WebP lossless images are 26% smaller in size compared to PNGs. WebP lossy images are 25-34% smaller than comparable JPEG images at equivalent SSIM quality index.
通过是否对图片进行压缩,我们可以分为:
- 无压缩。不对图片数据进行压缩处理,能准确地呈现原图片;
- 无损压缩。压缩算法对图片的所有的数据进行编码压缩,能在保证图片的质量的同时降低图片的尺寸。
- 有损压缩。压缩算法不会对图片所有的数据进行编码压缩,而是在压缩的时候,去除了人眼无法识别的图片细节,因此有损压缩可以在同等图片质量的情况下大幅降低图片的尺寸。
简单来说,WebP图片格式的存在,让我们在Web上展示的图片体积可以有较大幅度的缩小,也就带来了加载性能的提升。
要生成一个WebP图片非常简单,只需要下载Google提供的cwebp工具,并且使用cwebp -q 70 picture_with_alpha.png -o picture_with_alpha.webp命令就可以转换了,并且转换出来的webp图片比原图会小不少。
安装
CentOS 7.9
安装libvips
webp-server从
0.6.0开始不再依赖libaom.so.3,开始依赖libvips.so.42,因此必须安装libvips 8.10.0或更高版本。安装libwebp
[root@ecs ~]# cd /usr/local/src [root@ecs src]# wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.3.2.tar.gz [root@ecs src]# tar -xzf libwebp-1.3.2.tar.gz [root@ecs src]# cd libwebp-1.3.2 [root@ecs libwebp-1.3.2]# ./configure --prefix=/usr/local --enable-libwebpmux --enable-libwebpdemux [root@ecs libwebp-1.3.2]# make -j$(nproc) && make install [root@ecs libwebp-1.3.2]# echo "export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:\$PKG_CONFIG_PATH" >> /etc/profile [root@ecs libwebp-1.3.2]# source /etc/profile [root@ecs libwebp-1.3.2]# pkg-config --modversion libwebp [root@ecs libwebp-1.3.2]# pkg-config --libs libwebp [root@ecs libwebp-1.3.2]# echo "/usr/local/lib" > /etc/ld.so.conf.d/libwebp.conf [root@ecs libwebp-1.3.2]# ldconfig [root@ecs libwebp-1.3.2]# ldconfig -p | grep libwebp [root@ecs libwebp-1.3.2]# webpinfo -version- pkg-config在编译程序时为编译器和构建系统(make、cmake)提供已安装库的元数据(头文件路径、库路径、依赖项、版本号等)。
- ldconfig配置动态链接器(Dynamic Linker),在运行程序时能够快速找到所需的共享库(.so)。
安装libimagequant
4.0之开始用Rust重写,编译前需先安装Rust工具链。因此推荐2.18.0,完全满足libvips功能要求。
[root@ecs ~]# cd /usr/local/src [root@ecs src]# git clone https://github.com/ImageOptim/libimagequant.git -b 2.18.0 [root@ecs src]# cd libimagequant [root@ecs libimagequant]# make static && make install安装niftiio
[root@ecs ~]# cd /usr/local/src [root@ecs src]# tar -zxvf nifti_clib-3.0.0.tar.gz [root@ecs src]# cd nifti_clib-3.0.0 [root@ecs nifti_clib-3.0.0]# yum install -y help2man [root@ecs nifti_clib-3.0.0]# cmake3 -DBUILD_SHARED_LIBS=ON \ -DNIFTI_USE_PACKAGING=ON \ -DUSE_CIFTI_CODE=ON \ -DUSE_FSL_CODE=ON \ -DNIFTI_BUILD_APPLICATIONS=ON \ -DTEST_INSTALL=ON \ -DDOWNLOAD_TEST_DATA=OFF . [root@ecs nifti_clib-3.0.0]# make && make install安装cfitsio
[root@ecs ~]# cd /usr/local/src [root@ecs src]# wget http://heasarc.gsfc.nasa.gov/FTP/software/fitsio/c/cfitsio_latest.tar.gz [root@ecs src]# tar -zxvf cfitsio_latest.tar.gz [root@ecs src]# cd cfitsio-4.6.4 [root@ecs cfitsio-4.6.4]# ./configure --prefix=/usr/local --enable-reentrant [root@ecs cfitsio-4.6.4]# make && make install安装libspng
[root@ecs ~]# cd /usr/loca/src [root@ecs src]# tar -zxvf libspng-0.7.4.tar.gz [root@ecs src]# cd libspng-0.7.4 && mkdir build && cd build [root@ecs build]# meson setup --prefix /usr/local .. [root@ecs build]# ninja [root@ecs build]# ninja install安装PDFium
[root@ecs ~]# cd /usr/local/src [root@ecs src]# wget https://github.com/bblanchon/pdfium-binaries/releases/latest/download/pdfium-linux-x64.tgz [root@ecs src]# tar -xvf pdfium-linux-x64.tgz -C /usr/local [root@ecs src]# cat /usr/local/VERSION MAJOR=153 MINOR=0 BUILD=7988 PATCH=0 [root@ecs src]# cat > /usr/local/lib/pkgconfig/pdfium.pc << EOF prefix=/usr/local exec_prefix=\${prefix} libdir=\${exec_prefix}/lib includedir=\${prefix}/include Name: PDFium Description: Google's PDF rendering engine Version: 153.0.7988 Libs: -L\${libdir} -lpdfium Cflags: -I\${includedir} EOF验证是否安装成功
[root@ecs ~]# pkg-config --modversion pdfium [root@ecs ~]# pkg-config --libs pdfium [root@ecs ~]# ldconfig -p | grep libpdfium [root@ecs ~]# ldd /usr/local/lib/libpdfium.so测试示例
[root@ecs ~]# cat > pdfium_test.cpp << EOF #include <fpdfview.h> int main() { FPDF_InitLibrary(); FPDF_DestroyLibrary(); return 0; } EOF [root@ecs ~]# g++ pdfium_test.cpp $(pkg-config --cflags --libs pdfium) -o pdfium_test [root@ecs ~]# ./pdfium_test没有任何报错则说明pdfium已经安装成功。
安装libvips
[root@ecs ~]# yum install -y gcc-c++ \ glib2-devel expat-devel \ fftw-devel ImageMagick-devel orc-devel lcms2-devel OpenEXR-devel openslide-devel \ poppler-glib-devel librsvg2-devel pango-devel \ libpng-devel libtiff-devel giflib-devel libjpeg-devel libgsf-devel libexif-devel [root@ecs ~]# wget https://gh-proxy.org/https://github.com/libvips/libvips/releases/download/v8.10.5/vips-8.10.5.tar.gz [root@ecs ~]# tar -zxvf vips-8.10.5.tar.gz && cd vips-8.10.5 [root@ecs vips-8.10.5]# ./configure --prefix=/usr/local --disable-static --enable-introspection=no \ --with-pdfium-includes=/usr/local/include \ --with-pdfium-libraries=/usr/local/pdfium/lib [root@ecs vips-8.10.5]# make && make install [root@ecs vips-8.10.5]# echo "/usr/local/lib" > /etc/ld.so.conf.d/vips.conf && ldconfig [root@ecs vips-8.10.5]# ldconfig -p | grep libvips注:
- 如果使用PDFium,则必须设置
--with-pdfium-includes和--with-pdfium-libraries,否则即使安装了PDFium,PDF import with PDFium依旧为no。 - pdfium优先级高于poppler-glib,一旦指定了pdfium,poppler-glib就会失效。
示例
pdf转jpg
[root@ecs ~]# vips copy input.pdf[dpi=72,page=0,n=1] output.jpgdpi:控制输出图片分辨率,默认值72,数值越大,清晰度越高,文件越大。page:指定转换起始页码(从0开始),不指定默认从第1页开始。n:指定连续转换的页数,-1表示起始页到文档结尾所有页。输出多图时,所有页面垂直拼接成一张长图。
python
import pyvips image = pyvips.Image.new_from_file('input.pdf', dpi=200, n=-1) image.write_to_file('output.jpg')javascript
const sharp = require('sharp'); (async () => { sharp('input.pdf', { page: 0 }) //设置宽度,高度自适应 .resize(1024) //输出高质量jpeg .jpeg({ quality: 100 }) .toFile('output.jpg'); })();
核心依赖库
- glib2-devel(glib 2.x开发包)缺少则报错:
configure: error: Package requirements (glib-2.0 >= 2.15 gmodule-2.0 gobject-2.0 gio-2.0) were not met。 - expat-devel(xml解析库)缺少则报错:
configure: error: Could not find the Expat library。
其它依赖库(缺少不影响编译libvips,但会缺少相应的功能)
库 配置项 功能 fftw-devel use fftw3 for FFT 快速傅里叶变换 ImageMagick-devel Magick package
Magick API version
load with libMagick
save with libMagickImageMagick格式支持 orc-devel accelerate loops with orc 提升图像处理速度 lcms2-devel ICC profile support with lcms 色彩管理(防止图片偏色) niftiio file import with niftiio NIfTI格式(核磁共振图像)支持 libheif file import with libheif 苹果HEIC/HEIF格式支持 OpenEXR-devel file import with OpenEXR 高动态范围(HDR)图像支持 openslide-devel file import with OpenSlide 全切片(显微镜切片)病理图像支持 matio-devel file import with matio MATLAB .mat数据支持 PDFium PDF import with PDFium Google PDF渲染引擎(poppler-glib二选一) poppler-glib-devel PDF import with poppler-glib pdf首页转图片 librsvg2-devel SVG import with librsvg-2.0 将矢量图转位图 cfitsio file import with cfitsio FITS(天文望远镜图像)格式支持 libwebp file import/export with libwebp WebP格式导入导出支持 pango-devel text rendering with pangoft2 文本渲染(图片加文字水印) libspng file import/export with libspng libpng替代品(libpng二选一) libimagequant support 8bpp PNG quantisation 8位png颜色量化 libtiff-devel file import/export with libtiff tiff格式支持 giflib-devel file import/export with giflib gif格式支持 libjpeg-devel file import/export with libjpeg jpg格式支持 libgsf-devel image pyramid export 多分辨率切片格式支持 libexif-devel use libexif to load/save JPEG metadata 读取/保存 jpeg exif信息
升级glibc
webp-server从
0.13.3开始依赖`GLIBC_2.34',必须升级glibc到2.34或更高版本。如果不想升级glibc,CentOS 7.9默认glibc支持的webp-server最高版本是
0.13.1。安装webp-server
[root@ecs ~]# useradd -s /sbin/nologin www [root@ecs ~]# mkdir -p /data/webps && chown www:www /data/webps && chmod 755 /data/webps [root@ecs ~]# wget --no-check-certificate https://gh-proxy.org/https://github.com/webp-sh/webp_server_go/releases/download/0.13.1/webp-server-linux-amd64 -O /usr/local/bin/webp-server [root@ecs ~]# chmod +x /usr/local/bin/webp-server [root@ecs ~]# yum install -y libaom-devel [root@ecs ~]# webp-server -dump-config > /data/webps/config.json [root@ecs ~]# sed -i -e "s#127.0.0.1#0.0.0.0#" \ -e "s#./pics#/data/wwwroot#" /data/webps/config.json [root@ecs ~]# webp-server --config=/data/webps/config.json预热模式(后台提前将
/opt/pics目录内的所有图片转换成webp并缓存)[root@ecs ~]# webp-server --config=/data/webps/config.json -prefetch -jobs=${nproc}-jobs=${nproc}控制-prefetch转换时使用的线程数,默认为CPU的内核数。
查看方式:grep -c 'processor' /proc/cpuinfo、lscpu | grep "^CPU(s)"或者nproc。
开机自启动
[root@ecs ~]# webp-server -dump-systemd > /lib/systemd/system/webp-server.service [root@ecs ~]# sed -i -e 's#WorkingDirectory=/opt/webps#WorkingDirectory=/data/webps#g' \ -e 's#/opt/webps/webp-server#/usr/local/bin/webp-server#g' \ -e 's#/opt/webps/config.json#/data/webps/config.json#g' \ /lib/systemd/system/webp-server.service [root@ecs ~]# systemctl daemon-reload [root@ecs ~]# systemctl enable --now webp-server注:使用
-dump-systemd参数生成的配置文件,webp-server的默认路径为:/opt/webps/webp-server,配置文件的默认路径:/opt/webps/config.json,需要修改为实际路径。
Docker部署
创建镜像
[root@ecs ~]# cd /usr/local/src [root@ecs src]# tar -zxvf webp_server_go-0.15.1.tar.gz && cd webp_server_go-0.15.1 [root@ecs webp_server_go-0.15.1]# cat > /tmp/trixie.tmp << 'DOCKERFILE' RUN rm -f /etc/apt/sources.list.d/*.sources /etc/apt/sources.list.d/*.list RUN cat > /etc/apt/sources.list <<EOF deb http://mirrors.aliyun.com/debian/ trixie main contrib non-free non-free-firmware deb http://mirrors.aliyun.com/debian/ trixie-updates main contrib non-free non-free-firmware deb http://mirrors.aliyun.com/debian-security/ trixie-security main contrib non-free non-free-firmware EOF ENV GOPROXY=https://mirrors.aliyun.com/goproxy/,direct/ DOCKERFILE [root@ecs webp_server_go-0.15.1]# sed -i -e '/golang:1.26-trixie/r /tmp/trixie.tmp' -e '/debian:trixie-slim/r /tmp/trixie.tmp' Dockerfile [root@ecs webp_server_go-0.15.1]# docker build -t webp-server-go --progress=plain --no-cache .或者直接使用官方镜像:
webpsh/webp-server-go。创建配置文件
[root@ecs ~]# mkdir -p /data/webps [root@ecs ~]# cat > /data/webps/config.json << EOF { "HOST": "0.0.0.0", "PORT": "3333", "QUALITY": "80", "IMG_PATH": "/opt/pics", "EXHAUST_PATH": "./exhaust", "IMG_MAP": {}, "ALLOWED_TYPES": ["jpg","png","jpeg","gif","bmp","svg","heic","nef"], "CONVERT_TYPES": ["webp"], "STRIP_METADATA": true, "ENABLE_EXTRA_PARAMS": true, "READ_BUFFER_SIZE": 4096, "CONCURRENCY": 262144, "DISABLE_KEEPALIVE": false, "CACHE_TTL": 259200 } EOF"ENABLE_EXTRA_PARAMS": true:允许图片url传参。
创建容器
[root@ecs ~]# docker run -d \ --restart always \ --name webp-server \ -p 3333:3333 \ -v /data/webps/exhaust:/opt/exhaust \ -v /data/webps/metadata:/opt/metadata \ -v /data/wwwroot:/opt/pics \ -v /data/webps/config.json:/etc/config.json:ro \ webp-server-go注:docker容器不支持访问宿主的软链接,通过
-v /data/webp/pics:/opt/pics,然后在/data/webp/pics中创建软件是无效的,必须使用-v /data/wwwroot/maisi:/opt/pics/maisi方式进行挂载。测试
拷贝baidu.png到宿主机
/data/wwwroot/:[root@ecs ~]# curl -I -H "Accept: image/webp" http://139.196.100.56:3333/baidu.png拷贝00248.jpg到宿主机
/data/wwwroot/maisi:[root@ecs ~]# curl -I -H "Accept: image/webp" http://139.196.100.56:3333/maisi/00248.jpg HTTP/1.1 200 OK Server: WebP Server Go Date: Sun, 02 Aug 2026 13:19:09 GMT Content-Type: image/webp Content-Length: 531136 X-Compression-Rate: 0.34 Accept-Ranges: bytes Last-Modified: Sun, 02 Aug 2026 13:02:04 GMT [root@ecs ~]# curl -I -H "Accept: image/webp" http://139.196.100.56:3333/maisi/00248.jpg?width=200 HTTP/1.1 200 OK Server: WebP Server Go Date: Sun, 02 Aug 2026 13:18:10 GMT Content-Type: image/webp Content-Length: 2734 X-Compression-Rate: 0.00 Accept-Ranges: bytes Last-Modified: Sun, 02 Aug 2026 13:15:35 GMT
整合nginx
server {
# CORS
add_header Access-Control-Allow-Origin '*.maisi.com';
add_header Access-Control-Allow-Methods 'GET,POST';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
# HSTS(强制浏览器在后续请求中只通过https与服务器通信)
add_header Strict-Transport-Security "max-age=15768000;includeSubDomains;preload" always;
# XXS-Protection
add_header X-XSS-Protection "1; mode=block";
# ssl
ssl_certificate ../cert/maisi.com.pem;
ssl_certificate_key ../cert/maisi.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location ~* \.(?:jpg|jpeg|gif|png)$ {
# 禁止cdn缓存
add_header Cache-Control 'private';
proxy_pass http://127.0.0.1:3333/maisi$request_uri;
proxy_set_header X-Real-IP $remote_addr;
proxy_hide_header X-Powered-By;
proxy_set_header HOST $http_host;
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
}
}