package probe import ( "fmt" "image" "os" "path/filepath" "strings" ) // supportImageTypes 支持的标准图片扩展名(大小写不敏感) var supportImageTypes = []string{ ".bmp", ".gif", ".jpg", ".jpeg", ".jpe", ".png", ".webp", ".psb", ".jfif", } // IsSupportImage 判断扩展名是否属于支持的图片格式 func IsSupportImage(ext string) bool { for _, t := range supportImageTypes { if strings.EqualFold(t, ext) { return true } } return false } // ProbeImage 统一探测图片尺寸: // 1. 特殊格式(webp/bmp/psd/psb)走专用解码器 // 2. 其余支持格式走 Go 标准库 image.DecodeConfig // 3. 标准库失败时用 ffprobe 兜底(ffmpeg 支持的图片格式更广,如 tiff/svg 等) // // ffprobePath 为空表示不启用 ffprobe 兜底;扩展名不属于支持格式时返回错误。 func ProbeImage(filePath, ffprobePath string) (*ProbeResult, error) { ext := strings.ToLower(filepath.Ext(filePath)) switch ext { case ".webp": return probeWebp(filePath) case ".bmp": return probeBmp(filePath) case ".psd", ".psb": return probePsd(filePath) } if !IsSupportImage(ext) { return nil, fmt.Errorf("不支持的图片格式: %s", ext) } if w, h, err := decodeConfig(filePath); err == nil { return &ProbeResult{Width: w, Height: h}, nil } if ffprobePath != "" { if res, err := ProbeMediaFile(ffprobePath, filePath); err == nil && res.HasVideo { return res, nil } } return nil, fmt.Errorf("无法读取图片尺寸: %s", filePath) } // decodeConfig 用 Go 标准库读取图片宽高 func decodeConfig(filePath string) (int, int, error) { f, err := os.Open(filePath) if err != nil { return 0, 0, err } defer f.Close() cfg, _, err := image.DecodeConfig(f) if err != nil { return 0, 0, err } return cfg.Width, cfg.Height, nil }