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 }