101 lines
2.4 KiB
Go
101 lines
2.4 KiB
Go
package vision
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"runtime"
|
|
)
|
|
|
|
// HEICConverter 定义了处理 HEIC/HEIF 转换的工具路径
|
|
var heicConverter string
|
|
|
|
// DetectHEICConverter 探测系统中可用的 HEIC 转换工具。
|
|
// 优先级: sips (macOS) > heif-convert (libheif) > magick (ImageMagick)
|
|
func DetectHEICConverter() string {
|
|
if heicConverter != "" {
|
|
return heicConverter
|
|
}
|
|
|
|
// 1. macOS 专属原生工具
|
|
if runtime.GOOS == "darwin" {
|
|
if p, err := exec.LookPath("sips"); err == nil {
|
|
heicConverter = p
|
|
return p
|
|
}
|
|
}
|
|
|
|
// 2. 跨平台开源工具 heif-convert (libheif)
|
|
if p, err := exec.LookPath("heif-convert"); err == nil {
|
|
heicConverter = p
|
|
return p
|
|
}
|
|
|
|
// 3. 跨平台全能工具 ImageMagick
|
|
if p, err := exec.LookPath("magick"); err == nil {
|
|
heicConverter = p
|
|
return p
|
|
}
|
|
|
|
// 记录警告信息,指导用户安装
|
|
printHEICWarning()
|
|
return ""
|
|
}
|
|
|
|
func printHEICWarning() {
|
|
fmt.Fprintln(os.Stderr, "⚠️ Warning: No HEIC converter found in PATH.")
|
|
switch runtime.GOOS {
|
|
case "darwin":
|
|
fmt.Fprintln(os.Stderr, " Hint: macOS should have 'sips' pre-installed.")
|
|
case "linux":
|
|
fmt.Fprintln(os.Stderr, " Hint: Install libheif: 'sudo apt install libheif-examples'")
|
|
case "windows":
|
|
fmt.Fprintln(os.Stderr, " Hint: Install ImageMagick or libheif for Windows.")
|
|
}
|
|
}
|
|
|
|
// ConvertHEIC 使用探测到的工具将 HEIC 转换为 PNG 临时文件
|
|
func ConvertHEIC(src, dst string) error {
|
|
cmdPath := DetectHEICConverter()
|
|
if cmdPath == "" {
|
|
return fmt.Errorf("no HEIC converter available")
|
|
}
|
|
|
|
var cmd *exec.Cmd
|
|
base := ""
|
|
if runtime.GOOS == "windows" {
|
|
// 简单处理 Windows 下的路径
|
|
base = cmdPath
|
|
} else {
|
|
// 仅获取文件名判断类型
|
|
// 这里简单处理,直接用 DetectHEICConverter 返回的路径
|
|
base = cmdPath
|
|
}
|
|
|
|
// 根据不同工具构造命令
|
|
if contains(base, "sips") {
|
|
// sips -s format png input --out output
|
|
cmd = exec.Command(cmdPath, "-s", "format", "png", src, "--out", dst)
|
|
} else if contains(base, "heif-convert") {
|
|
// heif-convert input output
|
|
cmd = exec.Command(cmdPath, src, dst)
|
|
} else if contains(base, "magick") {
|
|
// magick input output.png
|
|
cmd = exec.Command(cmdPath, src, dst)
|
|
} else {
|
|
return fmt.Errorf("unsupported converter: %s", cmdPath)
|
|
}
|
|
|
|
return cmd.Run()
|
|
}
|
|
|
|
func contains(s, substr string) bool {
|
|
// 简单的字符串包含判断
|
|
for i := 0; i <= len(s)-len(substr); i++ {
|
|
if s[i:i+len(substr)] == substr {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|