- 删除已弃用的 compositor_client.go - 删除激光合成微服务代码 - 添加 gateway 合成控制器和测试文件 - 添加 Dify prompt 补丁脚本 Co-Authored-By: Claude <noreply@anthropic.com>
98 lines
2.1 KiB
Go
98 lines
2.1 KiB
Go
package compositor
|
||
|
||
import (
|
||
"fmt"
|
||
"image"
|
||
"image/color"
|
||
"image/png"
|
||
"net/http"
|
||
"strings"
|
||
"time"
|
||
_ "image/jpeg"
|
||
)
|
||
|
||
var httpClient = &http.Client{
|
||
Timeout: 30 * time.Second,
|
||
}
|
||
|
||
// DownloadImage 从 URL 下载并解码图片,返回 image.Image
|
||
func DownloadImage(url string) (image.Image, error) {
|
||
url = strings.TrimSpace(url)
|
||
if url == "" {
|
||
return nil, fmt.Errorf("empty URL")
|
||
}
|
||
|
||
resp, err := httpClient.Get(url)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("download failed: %w", err)
|
||
}
|
||
defer resp.Body.Close()
|
||
|
||
if resp.StatusCode != http.StatusOK {
|
||
return nil, fmt.Errorf("download returned HTTP %d", resp.StatusCode)
|
||
}
|
||
|
||
img, _, err := image.Decode(resp.Body)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("decode failed: %w", err)
|
||
}
|
||
|
||
return img, nil
|
||
}
|
||
|
||
// DownloadDecodePNG 下载并强制解码为 PNG(获取 alpha 通道)
|
||
func DownloadDecodePNG(url string) (image.Image, error) {
|
||
url = strings.TrimSpace(url)
|
||
if url == "" {
|
||
return nil, fmt.Errorf("empty URL")
|
||
}
|
||
|
||
resp, err := httpClient.Get(url)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("download failed: %w", err)
|
||
}
|
||
defer resp.Body.Close()
|
||
|
||
if resp.StatusCode != http.StatusOK {
|
||
return nil, fmt.Errorf("download returned HTTP %d", resp.StatusCode)
|
||
}
|
||
|
||
img, err := png.Decode(resp.Body)
|
||
if err != nil {
|
||
return DownloadImage(url)
|
||
}
|
||
|
||
return img, nil
|
||
}
|
||
|
||
// ExtractAlpha 将白色/浅灰背景转换为透明,保留非白色像素
|
||
func ExtractAlpha(img image.Image) *image.NRGBA {
|
||
bounds := img.Bounds()
|
||
result := image.NewNRGBA(bounds)
|
||
|
||
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
|
||
for x := bounds.Min.X; x < bounds.Max.X; x++ {
|
||
r, g, b, a := img.At(x, y).RGBA()
|
||
|
||
rf := float64(r) / 65535.0
|
||
gf := float64(g) / 65535.0
|
||
bf := float64(b) / 65535.0
|
||
|
||
// 亮度 > 90% 的视为白色/浅灰背景,设为透明
|
||
luminance := (rf + gf + bf) / 3.0
|
||
if luminance > 0.90 {
|
||
result.SetNRGBA(x, y, color.NRGBA{R: 0, G: 0, B: 0, A: 0})
|
||
} else {
|
||
result.SetNRGBA(x, y, color.NRGBA{
|
||
R: uint8(r >> 8),
|
||
G: uint8(g >> 8),
|
||
B: uint8(b >> 8),
|
||
A: uint8(a >> 8),
|
||
})
|
||
}
|
||
}
|
||
}
|
||
|
||
return result
|
||
}
|