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.jpg
      • dpi:控制输出图片分辨率,默认值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-develuse fftw3 for FFT快速傅里叶变换
    ImageMagick-develMagick package
    Magick API version
    load with libMagick
    save with libMagick
    ImageMagick格式支持
    orc-develaccelerate loops with orc提升图像处理速度
    lcms2-develICC profile support with lcms色彩管理(防止图片偏色)
    niftiiofile import with niftiioNIfTI格式(核磁共振图像)支持
    libheiffile import with libheif苹果HEIC/HEIF格式支持
    OpenEXR-develfile import with OpenEXR高动态范围(HDR)图像支持
    openslide-develfile import with OpenSlide全切片(显微镜切片)病理图像支持
    matio-develfile import with matioMATLAB .mat数据支持
    PDFiumPDF import with PDFiumGoogle PDF渲染引擎(poppler-glib二选一)
    poppler-glib-develPDF import with poppler-glibpdf首页转图片
    librsvg2-develSVG import with librsvg-2.0将矢量图转位图
    cfitsiofile import with cfitsioFITS(天文望远镜图像)格式支持
    libwebpfile import/export with libwebpWebP格式导入导出支持
    pango-develtext rendering with pangoft2文本渲染(图片加文字水印)
    libspngfile import/export with libspnglibpng替代品(libpng二选一)
    libimagequantsupport 8bpp PNG quantisation8位png颜色量化
    libtiff-develfile import/export with libtifftiff格式支持
    giflib-develfile import/export with giflibgif格式支持
    libjpeg-develfile import/export with libjpegjpg格式支持
    libgsf-develimage pyramid export多分辨率切片格式支持
    libexif-develuse 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/cpuinfolscpu | 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部署

  1. 创建镜像

    [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

  2. 创建配置文件

    [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传参。
  3. 创建容器

    [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方式进行挂载。

  4. 测试

    • 拷贝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';
    }

}

标签: none

添加新评论