错误的原因
图片缩放要用这个包: "golang.org/x/image/draw",标准库里面的包不支持缩放。
解析图片的时候,需要先注册解析器,才能去解析,否则会报错
func TrimImage() {
// 打开原始图片文件
f, err := os.Open("../../../uml/add_favor.png")
if err != nil {
log.Fatal(err)
}
defer f.Close()
// 解码图片
img, ff, err := image.Decode(f) //这个方法需要先注册对应图片类型的解析器,否则会报错,png和jpeg的解析器都在对应包的init方法里面
if err != nil {
log.Fatal(err, ff)
}
trimImage(img)
}
不注册解析器对应的报错
正确的代码
package utils
import (
"bytes"
"encoding/base64"
"image"
_ "image/gif" //注册gif对应的解析器
"image/jpeg"
_ "image/png" //注册png对应的解析器
"log"
"os"
_ "golang.org/x/image/bmp" //注册bmp对应的解析器
"golang.org/x/image/draw"
_ "golang.org/x/image/tiff" //注册tiff对应的解析器
_ "golang.org/x/image/webp" //注册webp对应的解析器
)
func TrimImage() {
// 打开原始图片文件
f, err := os.Open("../../../uml/add_favor.png")
if err != nil {
log.Fatal(err)
}
defer f.Close()
// 解码图片
img, ff, err := image.Decode(f)
if err != nil {
log.Fatal(err, ff)
}
trimImage(img)
}
type ImageTrimRes struct {
Width int
Height int
ThumbData []byte
}
func trimImage(img image.Image) *ImageTrimRes {
// 计算宽高比
width := img.Bounds().Dx()
height := img.Bounds().Dy()
ratio := float64(width) / float64(height)
// 计算目标宽高
var targetWidth, targetHeight int
if width > height {
targetWidth = 50
targetHeight = int(float64(targetWidth) / ratio)
} else {
targetHeight = 50
targetWidth = int(float64(targetHeight) * ratio)
}
// 缩放图片
dst := image.NewRGBA(image.Rect(0, 0, targetWidth, targetHeight))
draw.CatmullRom.Scale(dst, dst.Bounds(), img, img.Bounds(), draw.Over, nil)
// 保存图片
//out, err := os.Create("cropped.png")
//if err != nil {
// log.Fatal(err)
//}
//defer out.Close()
//png.Encode(out, dst)
// 转jpeg
//out, err := os.Create("cropped.jpeg")
//if err != nil {
// log.Fatal(err)
//}
//defer out.Close()
// 将图片保存为JPEG格式
//err := jpeg.Encode(out, dst, &opts)
//if err != nil {
// log.Fatal(err)
//}
// 设置JPEG压缩选项
opts := &jpeg.Options{
Quality: 90, // 设置压缩质量为90%
}
// 将图片转为字节流
var buf bytes.Buffer
err := jpeg.Encode(&buf, img, opts)
if err != nil {
log.Fatal(err)
}
// 字节流进行base64编码
byteSlice := buf.Bytes()
var resBytes []byte
base64.StdEncoding.Encode(resBytes, byteSlice)
return &ImageTrimRes{
Width: width,
Height: height,
ThumbData: resBytes,
}
}
func TestTrimImage(t *testing.T) {
TrimImage()
}
使用场景
比如发图片消息的时候,需要缩略模糊图和长宽信息让客户端进行预览和渲染,所以需要服务端处理图片。
一般云服务厂商也提供了这种能力,比如阿里云你在长传一个图片以后,支持你下载该图片对应的缩略图,只是url需要做一些处理