# 优雅的让 Halo 支持 webp 图片输出

原文：<https://www.halo.run/archives/halo-and-webp>

## 是什么

> WebP的有损压缩算法是基于VP8视频格式的帧内编码\[17\]，并以RIFF作为容器格式。\[2\] 因此，它是一个具有八位色彩深度和以1:2的比例进行色度子采样的亮度-色度模型（YCbCr 4:2:0）的基于块的转换方案。\[18\] 不含内容的情况下，RIFF容器要求只需20字节的开销，依然能保存额外的 元数据(metadata)。\[2\] WebP图像的边长限制为16383像素。

在 WebP 的官网中，我们可以发现 Google 是这样宣传 WebP 的：

> 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 图片格式的存在，让我们在 WebP 上展示的图片体积可以有较大幅度的缩小，也就带来了加载性能的提升。（摘自 [https://nova.moe/re-introduce-webp-server](https://nova.moe/re-introduce-webp-server))

## 怎么做

那么如何优雅的在不替换图片地址的情况下，将图片转为 webp 格式然后输出呢？

这时候就可以使用 [webp-sh](https://github.com/webp-sh) 组织最新开源的 [webp\_server\_go](https://github.com/webp-sh/webp_server_go) 了，它的大概原理就是：当我们请求一张图片的时候使用 web 代理工具转发到 `webp_server_go` 应用进行处理，处理完成之后返回 webp 格式的图片，并且会保留处理后的图片以供后面的访问。

目前大部分主流浏览器都已经支持了 webp 图片的显示，除了 Safari，但是不必担心，webp\_server\_go 会自动判断请求来源是否为 Safari，如果是，那么会返回原图。

下面将提供两种 web 服务器的代理方法。

> 此教程以 CentOS 7.x 为例，其他发行版本大同小异。另外，此教程只针对于 Halo，其他 web 程序可能在 config.json 部分有所不同，建议参考仓库的 README。

### 部署 webp\_server\_go

在 [仓库](https://github.com/webp-sh/webp_server_go) 的 README 中已经大致讲解了部署方法，在这里针对 Halo 详细说明一下。

#### 下载官方编译好的 webp\_server\_go 二进制文件

> 如果你有能力，也可以自行编译。

新建一个存放二进制文件和 config.json 文件的目录（可自定义）：

```shellscript
mkdir /opt/webps

cd /opt/webps
```

下载二进制文件（最新版本请访问 [releases](https://github.com/webp-sh/webp_server_go/releases)）：

```shellscript
wget https://github.com/webp-sh/webp_server_go/releases/download/0.1.0/webp-server-linux-amd64 -O webp-server
```

给予执行权限：

```shellscript
chmod +x webp-server
```

#### 创建 config.json

```json
{
        "HOST": "127.0.0.1",
        "PORT": "3333",
        "QUALITY": "80",
        "IMG_PATH": "/root/.halo",
        "EXHAUST_PATH": "/root/.halo/cache",
        "ALLOWED_TYPES": ["jpg","png","jpeg"]
}
```

参数解释：

-   HOST：一般不修改。
    
-   PORT：webp\_server\_go 的运行端口。
    
-   QUALITY：转换质量，默认为 80%。
    
-   IMG\_PATH：固定格式，/运行 Halo 的用户名/.halo
    
-   EXHAUST\_PATH：固定格式，/运行 Halo 的用户名/.halo/cache
    
-   ALLOWED\_TYPES：需要转换的格式
    

#### 使用 systemd 进行状态管理

创建 service 文件：

```shellscript
vim /etc/systemd/system/webps.service
```

写入：

```ini
[Unit]
Description=WebP Server
Documentation=https://github.com/n0vad3v/webp_server_go
After=nginx.target

[Service]
Type=simple
StandardError=journal
AmbientCapabilities=CAP_NET_BIND_SERVICE
WorkingDirectory=/opt/webps
ExecStart=/opt/webps/webp-server --config /opt/webps/config.json
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=3s


[Install]
WantedBy=multi-user.target
```

需要注意的是，ExecStart 命令中的程序路径和配置文件路径一定要正确，结合你的实际情况填写。

然后执行：

```shellscript
systemctl daemon-reload
systemctl enable webps.service
systemctl start webps.service
```

查看运行状态：

```shellscript
systemctl status webps.service
```

如果没有问题，那么会输出以下日志：

```shellscript
WebP Server is running at 127.0.0.1:3333
```

### 使用 Nginx 进行代理

> 如果你的 Halo 是使用 Nginx 反向代理的话。

#### 修改 halo.conf

在 server 节点添加：

```nginx
location ^~ /upload/ {
        proxy_pass http://127.0.0.1:3333;
        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';
}
```

重载 Nginx 配置：

```shellscript
# 检查配置文件是否有问题
nginx -t 

nginx -s reload
```

### 使用 Caddy 进行代理

> 如果你的 Halo 是使用 Caddy 反向代理的话。

#### 修改 Caddyfile

在你域名节点下添加：

```html
proxy /upload/ localhost:3333 {
  transparent
}
```

重启 Caddy：

```shellscript
service caddy restart
```

教程完毕，下面讲一下如何验证是否生效。

### 验证是否生效

![Screen Shot 2020-03-02 at 11.47.08 PM](https://halo.run/upload/2020/3/Screen%20Shot%202020-03-02%20at%2011.47.08%20PM-045cd797c4e3464a9d6919447a7d9e7f.png)

注意看 `Type` 列，图片的返回格式已经变成了 webp，而且图片大小已经远远降低，那么说明你的配置已经成功了。have fun!

如果用的开心，请关注一下 [https://github.com/webp-sh/webp\_server\_go](https://github.com/webp-sh/webp_server_go) 哦！另外，他们还有其他语言的版本，请查看 [https://github.com/webp-sh](https://github.com/webp-sh)。

### 链接：

-   [https://github.com/webp-sh/webp\_server\_go](https://github.com/webp-sh/webp_server_go)
    
-   [让站点图片加载速度更快——引入 WebP Server 无缝转换图片为 WebP](https://nova.moe/re-introduce-webp-server/)
    
-   [个人网站无缝切换图片到 webp](https://www.bennythink.com/flying-webp.html)
