ffmpeg_classify_ratio_landscape
FFmpeg 图片按宽高比自动分类(横屏)
补充说明
本文提供 Windows PowerShell 脚本,用于批量识别图片宽高比并自动分类归档。脚本通过 ffprobe 获取每张图片的分辨率,计算宽高比并匹配最接近的常见比例(±5% 容差),将图片自动移动到对应比例的目录中,绝不修改原始图片。
通用参数说明
- 源目录:
C:\Users\meimo\Downloads\landscape\- 容差范围:±5%(匹配阈值 0.05)
- 输出方式:按比例目录自动分类存放
- 支持格式:webp / jpg / jpeg / png / bmp / jfif
分类逻辑
- 扫描源目录所有图片文件
- 调用
ffprobe提取宽高分辨率 - 计算宽高比(宽度 ÷ 高度)
- 与预定义常见比例逐一比对,取最接近项
- 误差小于 5% 归入对应目录,否则归入
other目录 - 输出分类统计结果
一键执行命令
# ============================================================
# 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
功能说明
- 智能比例匹配:自动识别 12 种常见横屏宽高比,精确到 ±5% 容差
- 自动创建目录:首次运行自动生成对应比例的文件夹,无需手动新建
- 原图绝对保护:仅移动文件位置,不修改、不覆盖任何原始图片
- 全格式兼容:支持 webp / jpg / jpeg / png / bmp / jfif 格式
- 统计输出:分类完成后自动输出各目录数量和占比
- 异常处理:未匹配的图片归入 other 目录,处理失败的图片单独计数
- 进度提示:每处理 20 张图片输出一次进度