feat: 增加 EXIF 旋转图片自动转正

- 解析 JPEG EXIF Orientation,方向 5/6/7/8 的竖拍横存图不再误入横屏目录
- 配置 ffmpeg 时用 ffmpeg 物理转正像素并保留原 EXIF;无 ffmpeg 时按显示方向归类
- 新增 ffmpeg.path / organize.rotateImages 配置项
- 补充 EXIF 解析与旋转幂等测试
This commit is contained in:
2025-05-19 21:15:58 +08:00
parent 0c96a7bb63
commit 66faed75a2
7 changed files with 459 additions and 6 deletions
+31 -1
View File
@@ -14,12 +14,14 @@ import (
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"sync"
"time"
"kenaito-media-picker/internal/config"
"kenaito-media-picker/internal/organize"
"kenaito-media-picker/internal/probe"
"kenaito-media-picker/internal/scanner"
@@ -270,6 +272,23 @@ func resolveRootDir(dir string) string {
return abs
}
// resolveFFmpegPath 确定 ffmpeg 程序的路径:
// - 配置里指定了就用配置的(不存在时退回下一步);
// - 否则在 PATH 里找 ffmpeg。
//
// 找不到返回空串(调用方会退化为"不转正、按显示方向归类")。
func resolveFFmpegPath(configured string) string {
if configured != "" {
if _, err := os.Stat(configured); err == nil {
return configured
}
}
if p, err := exec.LookPath("ffmpeg"); err == nil {
return p
}
return ""
}
// ============================ 后台任务本体 ============================
// run 是后台干活线程。除了调用 runScan 真正干活外,它还要做一件特殊的事:
@@ -410,7 +429,18 @@ func (s *ScanService) runScan(rootDir, destDir string) error {
}
// ---------- 第四步:整理 ----------
org := organize.New(pickerDir, ffprobePath, s.store)
// ffmpeg 用于把带 EXIF 旋转标记的图片转正(竖拍的图文件里横着存,显示才竖起来)。
// 找不到 ffmpeg 也没关系——图片照常处理,只是不转正、按显示方向归类。
ffmpegPath := ""
if config.GetAppConfig().RotateImages {
ffmpegPath = resolveFFmpegPath(config.GetAppConfig().FFmpegPath)
if ffmpegPath == "" {
fmt.Println("=== 未找到 ffmpeg, 图片EXIF旋转将不做物理转正(仍按显示方向归类)")
} else {
fmt.Printf("=== 使用 ffmpeg 转正图片EXIF旋转: %s\n", ffmpegPath)
}
}
org := organize.New(pickerDir, ffprobePath, ffmpegPath, s.store)
// 整个"整理"分两个阶段,界面上共用一条进度条:
// 归类阶段:图片、视频/音频分两批处理。进度 = 已处理文件数 / 全部待整理文件数