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

ffmpeg_classify_ratio_portrait

命令

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

ffmpeg_classify_ratio_portrait

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

补充说明

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

通用参数说明

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

分类逻辑

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

目录命名规范

无论横屏还是竖屏,目录名都是 宽x高(宽度在前,高度在后)

类型 目录名格式 示例 示例分辨率 比例计算
横屏 宽x高 16x9\ 1920×1080 宽/高 = 1.778
竖屏 宽x高 9x16\ 1080×1920 高/宽 = 1.778

一键执行命令

# ============================================================
# 竖屏图片按宽高比自动分类(最终修正版)
# 支持比例:1:1, 4:5, 3:4, 2:3, 10:16, 9:16, 6:13, 9:20
# 容差:±5%
# 目录命名:宽度x高度(如 6x13\、9x20\)
# ============================================================

# 定义常见竖屏宽高比(宽度:高度)
$commonRatios = @(
    @{Name="1x1"; Ratio=1.0; Dir="1x1"},          # 1.0 (正方形)
    @{Name="4x5"; Ratio=1.25; Dir="4x5"},        # 1.25 (4:5 竖版)
    @{Name="3x4"; Ratio=1.333; Dir="3x4"},      # 1.333 (3:4 竖版)
    @{Name="2x3"; Ratio=1.5; Dir="2x3"},         # 1.5 (2:3 竖版)
    @{Name="10x16"; Ratio=1.6; Dir="10x16"},     # 1.6 (10:16 竖版)
    @{Name="9x16"; Ratio=1.778; Dir="9x16"},     # 1.778 (9:16 竖版)
    @{Name="6x13"; Ratio=13/6; Dir="6x13"},      # 2.167 (6:13 全面屏竖版)
    @{Name="9x20"; Ratio=20/9; Dir="9x20"}       # 2.222 (9:20 超宽全面屏)
)

# 获取所有图片文件(排除子目录)
$imageFiles = Get-ChildItem -Path "C:\Users\meimo\Downloads\portrait" -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
$landscapeCount = 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]
            
            # 判断是否为竖屏(高度 > 宽度)
            if ($height -le $width) {
                $landscapeCount++
                Write-Host "⏭️  跳过横屏图片: $($file.Name) ($width x $height)" -ForegroundColor Yellow
                continue
            }
            
            # 计算竖屏宽高比(高/宽)
            $actualRatio = $height / $width
            
            # 找到最接近的常见比例
            $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\portrait\$($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\portrait\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
                
                if (!$ratioStats["other"]) {
                    $ratioStats["other"] = 0
                }
                $ratioStats["other"]++
                $movedCount++
            }
        }
    }
    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 "⏭️  跳过横屏图片: $landscapeCount 个" -ForegroundColor Yellow
Write-Host "❌ 处理失败: $errorCount 个`n" -ForegroundColor Red

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

支持的比例

目录名 宽度:高度 高/宽 常见分辨率 设备示例
1x1\ 1:1 1.0 1080×1080 社交媒体头像
4x5\ 4:5 1.25 864×1080 打印照片(4×5 寸)
3x4\ 3:4 1.333 810×1080 旧式照片竖版
2x3\ 2:3 1.5 720×1080 135 胶片竖版
10x16\ 10:16 1.6 675×1080 某些相机竖拍
9x16\ 9:16 1.778 1080×1920 传统手机竖屏
6x13\ 6:13 2.167 1080×2340 全面屏手机
9x20\ 9:20 2.222 1440×3200 超宽全面屏

比例详解

6:13 比例

9:20 比例


执行后的目录结构

C:\Users\meimo\Downloads\portrait\
├── 6x13\          (全面屏手机竖版)
├── 9x20\          (超宽全面屏)
├── 9x16\          (标准手机竖屏)
├── 2x3\           (135 胶片竖版)
├── 3x4\           (旧式照片竖版)
├── 4x5\           (打印照片)
├── 10x16\         (相机竖拍)
├── 1x1\           (正方形)
└── other\         (非常见比例)

自定义修改

修改容差(默认 ±5%)

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

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

添加新比例

$commonRatios 数组中添加:

$commonRatios = @(
    ...
    @{Name="16x9"; Ratio=16/9; Dir="16x9"}       # 横屏 16:9
)

修改源目录

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

验证结果

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

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

后续操作

# 查看其他目录中的非常见比例图片
Get-ChildItem "C:\Users\meimo\Downloads\portrait\other" | ForEach-Object {
    $result = & ffprobe -v error -select_streams v:0 `
        -show_entries stream=width,height -of csv=p=0 $_.FullName
    $width = [int]($result -split ',')[0]
    $height = [int]($result -split ',')[1]
    "$($_.Name): $width x $height (竖屏比例: $([math]::Round($height/$width, 4)))"
}

# 批量添加比例前缀(可选)
Get-ChildItem "C:\Users\meimo\Downloads\portrait\6x13" | ForEach-Object {
    $newName = "6x13_$($_.Name)"
    Rename-Item $_.FullName -NewName $newName -Force
}

常见问题

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

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

解决

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

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

2. 横屏图片被跳过

脚本会自动过滤横屏图片(高度 ≤ 宽度),这些图片不会被移动。如需分类横屏图片,请使用 ffmpeg_classify_ratio_landscape 脚本。

3. 实际比例与理论比例不一致

很多手机标注 "20:9",但实际像素可能是 6:13 (2.167) 或 19.5:9。厂商宣传比例 vs 实际像素存在误差,±5% 容差可以覆盖。


功能说明