很多云服务商都提供图片静态资源的在线调整尺寸的服务,对于个人小应用来说,使用这些厂商的服务很麻烦,而且还需要额外的开销。比如我希望白嫖CloudFlare的cdn,那就得另想办法。而ImgProxy就是目前我能找到的最好的解决方案,它可以原始图片进行压缩,裁剪,旋转,模糊等一系列操作,进而减少流量。比如原图可能是8K大小的图,大概15M左右,当我需要图像列表的时候,实时处理成320×240大小的图,也就几K大小,这样一来,网页打开的速度也大大加快。
根据官方给出的架构图,可以大致确定一个运行方式,即:
- 需要一个源图地址的CDN域名
- 需要一个imgproxy的CDN域名
同时官方也给出了一个市面上类似应用的对比图,由于imgproxy是go写的,所以无论是内存占用还是性能上,表现都很出色,同时使用简单,非常适用于一些个人项目,或者不太大的商业项目。
前面说了,需要两个CDN域名,之所以源图资源需要CDN,因为imgproxy最终的url其实就是一堆base64编码的东西,解码出来其实就是源图地址,如果源图不加CDN的话,可能就被干爆了。
用docker来搭一个imgproxy也很简单,下面是docker-compose的例子
version: "3.3"
services:
imgproxy:
image: darthsim/imgproxy
container_name: imgproxy
restart: always
networks:
- work-net
environment:
# 读取源文件超时秒数
- IMGPROXY_READ_TIMEOUT=30
# 可以处理的原图最大分辨率,百万,举例:8K分辨率为7680 × 4320 约3300万,对应处理的值就是33
- IMGPROXY_MAX_SRC_RESOLUTION=100
# 发送给浏览器的图片缓存秒数,180天
- IMGPROXY_TTL=15552000
# 日志级别
- IMGPROXY_LOG_LEVEL=error
# 加密用的KEY/SALT
- IMGPROXY_KEY=a14cd90aad80d
- IMGPROXY_SALT=404a64f2e43ee
labels:
# imgproxy
- "traefik.enable=true"
- "traefik.http.routers.imgproxy.rule=Host(`imgproxy.anerg.com`)"
- "traefik.http.routers.imgproxy.entrypoints=websecure"
- "traefik.http.services.imgproxy.loadbalancer.server.port=8080"
- "traefik.http.routers.imgproxy.service=imgproxy"
- "traefik.http.routers.imgproxy.tls=true"
- "traefik.http.routers.imgproxy.tls.certresolver=cloudflare"
networks:
work-net:
external: true
我只配置了我认为比较重要的参数。因为我不想这个服务被白嫖,那么就要加上加密,例子中相关参数已经有解释了,关于KEY和SALT,根据官方文档,可以用以下命令生成。
echo $(xxd -g 2 -l 64 -p /dev/random | tr -d '\n')
最终生成的url地址大概会是这样的
https://imgproxy.anerg.com/eE5pJp-yowc/w:300/h:400/q:100/aHR0cHM6Ly9tLm1l.jpg
其中eE5pJp-yow
这一段就是加密,w:300/h:400/q:100是对图片的操作,aHR0cHM6Ly9tLm1l是图片实际的url地址的base64编码。
具体的可以参考官方文档的说明:https://docs.imgproxy.net/
同时我也写了一个golang的操作库,https://github.com/anerg2046/imgproxy-go
除了付费pro版的操作,其他方法基本都支持了,用法也很简单
package main
import (
"fmt"
imgproxygo "github.com/anerg2046/imgproxy-go"
)
func main() {
imgproxy := imgproxygo.N(imgproxygo.Config{
BaseUrl: "http://localhost:8080",
Key: "736563726574",
Salt: "68656C6C6F",
SignatureSize: 8,
Encode: true,
})
s := imgproxy.Builder().Width(300).Height(400).Quality(100).Gen("https://m.media-amazon.com/images/M/MV5BMmQ3ZmY4NzYtY2VmYi00ZDRmLTgyODAtZWYzZjhlNzk1NzU2XkEyXkFqcGdeQXVyNTc3MjUzNTI@.jpg")
fmt.Println(s)
}
总结
对于白嫖党来说,这个东西基本是个vps都能跑的起来,性能高,占用小,是个很不错的东西,但是需要一点动手能力才能折腾。