Files
ai/models/Image.go
2023-06-07 14:25:04 +08:00

102 lines
3.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 {
ID int `json:"id" gorm:"primary_key"`
Name string `json:"name"`
Hash string `json:"hash"`
Path string `json:"path"`
Type string `json:"type"`
Size int `json:"size"`
Width int `json:"width"`
Height int `json:"height"`
Prompt string `json:"prompt"`
Format string `json:"format"`
NegativePrompt string `json:"negative_prompt"`
NumInferenceSteps int `json:"num_inference_steps"` // Number of inference steps (minimum: 1; maximum: 500)
GuidanceScale float32 `json:"guidance_scale"` // Scale for classifier-free guidance (minimum: 1; maximum: 20)
Scheduler string `json:"scheduler"` // (DDIM|K_EULER|DPMSolverMultistep|K_EULER_ANCESTRAL|PNDM|KLMS)
Seed int `json:"seed"` // Random seed (minimum: 0; maximum: 2147483647)
FromImage string `json:"from_image"` // Image to start from
UserID int `json:"user_id"`
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"`
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{})
}
type ImageList []string
func (list *ImageList) Scan(value interface{}) error {
return json.Unmarshal(value.([]byte), list)
}
func (list ImageList) Value() (driver.Value, error) {
return json.Marshal(list)
}