Files
deskview/internal/vision/encode.go
T
2026-10-27 17:58:28 +08:00

46 lines
1.1 KiB
Go

package vision
import (
"bytes"
"fmt"
"image"
"image/jpeg"
"golang.org/x/image/draw"
)
// EncodeJPEG 把图像等比缩放到长边不超过 maxEdge 后编码为 JPEG。
// 视觉模型对分辨率不敏感,但对 token 很敏感,这一步是成本控制的关键。
func EncodeJPEG(img image.Image, maxEdge, quality int) ([]byte, error) {
if img == nil {
return nil, fmt.Errorf("待编码图像为空")
}
if maxEdge <= 0 {
maxEdge = 1280
}
if quality <= 0 || quality > 100 {
quality = 75
}
b := img.Bounds()
w, h := b.Dx(), b.Dy()
if w <= 0 || h <= 0 {
return nil, fmt.Errorf("图像尺寸无效: %dx%d", w, h)
}
target := img
if longest := max(w, h); longest > maxEdge {
scale := float64(maxEdge) / float64(longest)
nw, nh := max(int(float64(w)*scale+0.5), 1), max(int(float64(h)*scale+0.5), 1)
dst := image.NewRGBA(image.Rect(0, 0, nw, nh))
draw.CatmullRom.Scale(dst, dst.Bounds(), img, b, draw.Src, nil)
target = dst
}
var buf bytes.Buffer
if err := jpeg.Encode(&buf, target, &jpeg.Options{Quality: quality}); err != nil {
return nil, fmt.Errorf("JPEG 编码失败: %w", err)
}
return buf.Bytes(), nil
}