This commit is contained in:
2023-06-07 00:37:59 +08:00
parent 61b1612610
commit 560151a72d
3 changed files with 80 additions and 1 deletions

View File

@@ -1,10 +1,18 @@
package models
import (
"bytes"
"database/sql/driver"
"encoding/json"
"fmt"
"image"
"io/ioutil"
"main/configs"
"time"
"github.com/chai2010/webp"
"github.com/disintegration/imaging"
giftowebp "github.com/sizeofint/gif-to-webp"
)
type Image struct {
@@ -24,6 +32,56 @@ type Image struct {
UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"`
}
// 将图片输出为指定尺寸的 webp 格式(默认使用 Lanczos 缩放算法)
func (img *Image) ToWebP(width int, height int, fit string) ([]byte, error) {
// 從絕對路徑讀原始圖片
data, err := ioutil.ReadFile(fmt.Sprintf("data/images/%d", img.ID))
if err != nil {
return nil, err
}
// 將原始圖片轉換為 Image
imageData, format, err := image.Decode(bytes.NewReader(data))
if err != nil {
return nil, err
}
// 如果原图是GIF格式的动态图片直接不作尺寸处理直接转换为webp格式
if format == "gif" {
converter := giftowebp.NewConverter()
converter.LoopCompatibility = true // 是否兼容循环动画
converter.WebPConfig.SetLossless(1) // 0 有损压缩 1无损压缩
converter.WebPConfig.SetMethod(6) // 压缩速度 0-6 0最快 6质量最好
converter.WebPConfig.SetQuality(100) // 压缩质量 0-100
converter.WebPAnimEncoderOptions.SetKmin(9)
converter.WebPAnimEncoderOptions.SetKmax(17)
return converter.Convert(data)
}
// 如果指定了宽高却没有指定fit, 则默认fit为cover
if width != 0 && height != 0 && fit == "" {
fit = "cover"
}
// 如果未指定宽高和fit, 则不缩放图片直接返回webp
if width == 0 && height == 0 && fit == "" {
return webp.EncodeRGBA(imageData, 100)
}
switch fit {
case "cover":
return webp.EncodeRGBA(imaging.Fill(imageData, width, height, imaging.Center, imaging.Lanczos), 100)
case "contain":
return webp.EncodeRGBA(imaging.Fit(imageData, width, height, imaging.Lanczos), 100)
case "fill":
return webp.EncodeRGBA(imaging.Fill(imageData, width, height, imaging.Center, imaging.Lanczos), 100)
case "inside":
return webp.EncodeRGBA(imaging.Fit(imageData, width, height, imaging.Lanczos), 100)
case "outside":
return webp.EncodeRGBA(imaging.Fill(imageData, width, height, imaging.Center, imaging.Lanczos), 100)
case "scale-down":
return webp.EncodeRGBA(imaging.Fit(imageData, width, height, imaging.Lanczos), 100)
default:
return webp.EncodeRGBA(imaging.Resize(imageData, width, height, imaging.Lanczos), 100)
}
}
func init() {
configs.ORMDB().AutoMigrate(&Image{})
}