Go语言根据URL动态生成指定宽高的缩略图
nginx里面有一个模块叫作 ngx_image_thumb,它是用来动态生成缩略图的,几年前我用过很多次。这个模块依赖GD库,主要达到的效果就是访问一个图片URL,在URL里面指定图片宽高,然后就动态输出一张指定宽高的图片,用完即废弃,不占用硬盘空间。
不过这个nginx模块安装非常麻烦,需要动态编译,如果不熟悉流程,很容易把 nginx 搞坏。现在我用Go语言实现同样的功能,在URL中指定图片的宽高然后把它动态输出,具体的效果是这样的:
点击上面的图片,查看它的地址,在地址中,300和280分别代表宽和高,你可以任意修改这两个值(只要符合规范)。下面来看Golang代码的实现。
// 引入第三方库用于压缩图片
import "github.com/disintegration/imaging"
func main() {
http.HandleFunc("/thumb/", func(w http.ResponseWriter, r *http.Request) {
path := strings.ToLower(r.URL.Path)
path = strings.Replace(path, "/thumb/", "", 1)
arr := strings.Split(path, "_")
alen := len(arr)
if alen != 3 {
log.Fatal("地址有误")
}
name := arr[0]
widthS := arr[1]
heightS := ""
fix := arr[2]
if idx := strings.Index(fix, "."); idx != -1 {
heightS = fix[:idx]
fix = fix[idx+1:]
}
width, err := strconv.Atoi(widthS)
if err != nil {
panic(err)
}
height, err := strconv.Atoi(heightS)
if err != nil {
panic(err)
}
f, err := os.Open("pic path 这里换成你的原图存放路径" + name + "." + fix)
if err != nil {
panic(err)
}
defer f.Close()
buf, err := io.ReadAll(f)
if err != nil {
panic(err)
}
if fix == "png" {
imgBuf, err := png.Decode(bytes.NewBuffer(buf))
if err != nil {
panic(err)
}
imgBuf = imaging.Fill(imgBuf, width, height, imaging.Center, imaging.Lanczos)
// 这里一定要指定输出的数据类型 这样才会显示图片
w.Header().Set("Content-Type", "image/png")
// 载入png图片 这里实际上就是 write buf
if err = png.Encode(w, imgBuf); err != nil {
panic(err)
}
}
})
}
生产环境请自行做优化和改动,上面的Go代码只是例子,也只处理了 png 图片,如果要处理 jpeg 和 gif,做法是一样的,多几个判断而已。Golang对图片压缩处理不好,原生并不支持压缩,所以这里使用了一个第三方库。
最终的缩略图的地址是:你的网站地址/thumb/图片名字宽高.png
声明: 因编程语言版本更新较快,当前文章所涉及的语法或某些特性相关的信息并不一定完全适用于您当前所使用的版本,请仔细甄别。文章内容仅作为学习和参考,若有错误,欢迎指正。
-
可以对这些缩略图进行缓存,例如加入到 redis 里面,这样就不会每次访问同一个图片地址都重新生成一遍了,因为这里要打开和关闭图片,是有磁盘IO的。
key := "article:thumb:图片路径" + name + "." + fix
if buf, err := rdsCli.Get(rdsCtx, key).Bytes(); redis.IsNotNill(err) {
panic(err)
} else if len(buf) != 0 {
// 输入图片
return
}
// 缓存图片
if err := rdsCli.Set(key, imgBuf , time.Hour*24); redis.IsNotNill(err) {
panic(err)
}
开发者
专题·造轮子
Golang·热门
相关文章