随机
Enter 搜索 ↑↓ 切换 Esc 清空

ffmpeg_classify_ratio_landscape

命令

FFmpeg 图片按宽高比自动分类(横屏)

ffmpeg_classify_ratio_landscape

FFmpeg 图片按宽高比自动分类(横屏)

补充说明

本文提供 Windows PowerShell 脚本,用于批量识别图片宽高比并自动分类归档。脚本通过 ffprobe 获取每张图片的分辨率,计算宽高比并匹配最接近的常见比例(±5% 容差),将图片自动移动到对应比例的目录中,绝不修改原始图片

通用参数说明

  • 源目录:C:\Users\meimo\Downloads\landscape\
  • 容差范围:±5%(匹配阈值 0.05)
  • 输出方式:按比例目录自动分类存放
  • 支持格式:webp / jpg / jpeg / png / bmp / jfif

分类逻辑

  1. 扫描源目录所有图片文件
  2. 调用 ffprobe 提取宽高分辨率
  3. 计算宽高比(宽度 ÷ 高度)
  4. 与预定义常见比例逐一比对,取最接近项
  5. 误差小于 5% 归入对应目录,否则归入 other 目录
  6. 输出分类统计结果

一键执行命令

# ============================================================
# Landscape 图片按宽高比自动分类(综合命令)
# 支持比例:4:3, 3:2, 16:10, 16:9, 17:9, 19:10, 2:1, 20:9, 21:9
# 容差:±5%
# ============================================================

# 定义常见宽高比
$commonRatios = @(
    @{Name="4x3"; Ratio=4/3; Dir="4x3"},          # 1.333
    @{Name="3x2"; Ratio=3/2; Dir="3x2"},          # 1.5
    @{Name="16x10"; Ratio=16/10; Dir="16x10"},    # 1.6
    @{Name="16x9"; Ratio=16/9; Dir="16x9"},      # 1.778
    @{Name="17x9"; Ratio=17/9; Dir="17x9"},      # 1.889
    @{Name="19x10"; Ratio=19/10; Dir="19x10"},    # 1.9
    @{Name="2x1"; Ratio=2.0; Dir="2x1"},         # 2.0
    @{Name="18x9"; Ratio=18/9; Dir="18x9"},      # 2.0
    @{Name="20x9"; Ratio=20/9; Dir="20x9"},      # 2.222
    @{Name="21x9"; Ratio=21/9; Dir="21x9"},      # 2.333
    @{Name="24x9"; Ratio=24/9; Dir="24x9"},      # 2.667
    @{Name="32x9"; Ratio=32/9; Dir="32x9"}       # 3.556
)

# 获取所有图片文件(排除子目录)
$imageFiles = Get-ChildItem -Path "C:\Users\meimo\Downloads\landscape" -File | Where-Object {
    $_.Extension -in '.webp', '.jpg', '.jpeg', '.png', '.bmp', '.jfif'
}

Write-Host "`n📊 开始智能比例分类..." -ForegroundColor Cyan
Write-Host "共 $($imageFiles.Count) 个图片文件`n" -ForegroundColor Cyan

# 统计哈希表
$ratioStats = @{}
$movedCount = 0
$errorCount = 0

foreach ($file in $imageFiles) {
    try {
        # 使用 ffprobe 获取图片分辨率
        $ffprobeArgs = @(
            '-v', 'error',
            '-select_streams', 'v:0',
            '-show_entries', 'stream=width,height',
            '-of', 'csv=p=0',
            $file.FullName
        )
        
        $result = & ffprobe $ffprobeArgs
        
        if ($result) {
            $dimensions = $result -split ','
            $width = [int]$dimensions[0]
            $height = [int]$dimensions[1]
            $actualRatio = $width / $height
            
            # 找到最接近的常见比例
            $bestMatch = $null
            $bestDiff = [double]::MaxValue
            
            foreach ($r in $commonRatios) {
                $diff = [math]::Abs($actualRatio - $r.Ratio)
                if ($diff -lt $bestDiff) {
                    $bestDiff = $diff
                    $bestMatch = $r
                }
            }
            
            # 如果误差小于 5%,归类到该比例
            if ($bestDiff -lt 0.05) {
                $targetDir = "C:\Users\meimo\Downloads\landscape\$($bestMatch.Dir)"
                
                # 创建目标目录
                if (!(Test-Path -Path $targetDir)) {
                    New-Item -ItemType Directory -Path $targetDir | Out-Null
                    Write-Host "✅ 已创建目录: $($bestMatch.Dir)" -ForegroundColor Green
                }
                
                # 移动文件
                $destPath = Join-Path $targetDir $file.Name
                Move-Item -Path $file.FullName -Destination $destPath -Force
                $movedCount++
                
                # 统计
                if (!$ratioStats[$bestMatch.Dir]) {
                    $ratioStats[$bestMatch.Dir] = 0
                }
                $ratioStats[$bestMatch.Dir]++
                
                if ($movedCount % 20 -eq 0) {
                    Write-Host "已处理: $movedCount 个图片" -ForegroundColor Cyan
                }
            } else {
                # 未匹配到常见比例,放到 other 目录
                $targetDir = "C:\Users\meimo\Downloads\landscape\other"
                if (!(Test-Path -Path $targetDir)) {
                    New-Item -ItemType Directory -Path $targetDir | Out-Null
                    Write-Host "✅ 已创建目录: other" -ForegroundColor Yellow
                }
                
                $destPath = Join-Path $targetDir $file.Name
                Move-Item -Path $file.FullName -Destination $destPath -Force
                $movedCount++
                
                if (!$ratioStats["other"]) {
                    $ratioStats["other"] = 0
                }
                $ratioStats["other"]++
            }
        }
    }
    catch {
        $errorCount++
        Write-Host "❌ 处理失败: $($file.Name)" -ForegroundColor Red
    }
}

# 输出统计结果
Write-Host "`n========== 分类完成 ==========" -ForegroundColor Green
Write-Host "`n📊 统计结果:`n" -ForegroundColor Cyan

foreach ($dir in $ratioStats.Keys | Sort-Object) {
    $count = $ratioStats[$dir]
    $percent = [math]::Round(($count / $imageFiles.Count) * 100, 1)
    Write-Host "  $dir`: $count 个图片 ($percent`)" -ForegroundColor Yellow
}

Write-Host "`n✅ 共处理 $movedCount 个图片!" -ForegroundColor Green
Write-Host "❌ 处理失败: $errorCount 个`n" -ForegroundColor Red

# 验证总数
$total = (Get-ChildItem "C:\Users\meimo\Downloads\landscape" -File -Recurse).Count
Write-Host "📁 总计: $total 个图片`n" -ForegroundColor Cyan

支持的比例

目录名 比例值 说明
4x3\ 1.333 旧式显示器、平板
3x2\ 1.5 标准照片(135 胶片)
16x10\ 1.6 笔记本屏幕
16x9\ 1.778 标准宽屏(HDTV)
17x9\ 1.889 超宽屏
19x10\ 1.9 宽幅模式(无人机)
2x1\ / 18x9\ 2.0 双倍宽屏
20x9\ 2.222 超超宽屏
21x9\ 2.333 曲面超宽屏
24x9\ 2.667 多屏拼接
32x9\ 3.556 极端宽屏
other\ - 非常见比例

执行后的目录结构

C:\Users\meimo\Downloads\landscape\
├── 16x9\          (标准 16:9 图片)
├── 16x10\         (16:10 图片)
├── 17x9\          (超宽屏 17:9 图片)
├── 19x10\         (宽幅 19:10 图片)
├── 2x1\           (2:1 图片)
├── 20x9\          (20:9 图片)
├── 21x9\          (21:9 图片)
├── 3x2\           (3:2 照片)
├── 4x3\           (4:3 图片)
├── other\         (非常见比例)
└── (无剩余文件)

自定义修改

修改容差(默认 ±5%)

# 改为 ±2%
if ($bestDiff -lt 0.02) { ... }

# 改为 ±10%
if ($bestDiff -lt 0.10) { ... }

添加新比例

$commonRatios 数组中添加:

$commonRatios = @(
    ...
    @{Name="1x1"; Ratio=1.0; Dir="1x1"},          # 正方形
    @{Name="9x16"; Ratio=9/16; Dir="9x16"}       # 竖屏
)

修改源目录

$imageFiles = Get-ChildItem -Path "你的目录路径" -File | Where-Object { ... }

验证结果

# 查看各目录文件数
Get-ChildItem "C:\Users\meimo\Downloads\landscape" -Directory | ForEach-Object {
    $count = (Get-ChildItem $_.FullName -File).Count
    "$($_.Name): $count 个文件"
}

# 检查总数
(Get-ChildItem "C:\Users\meimo\Downloads\landscape" -File -Recurse).Count

常见问题

1. ffprobe 不是内部或外部命令

原因:未安装 FFmpeg 或未添加到 PATH

解决

# 检查 ffprobe 是否在 PATH 中
Get-Command ffprobe -ErrorAction SilentlyContinue

# 如果未找到,需要安装 FFmpeg 并添加到 PATH

功能说明