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 }