提问人:AL2044 提问时间:11/16/2023 更新时间:11/21/2023 访问量:76
有没有办法通过 Windows Batch 删除文件夹中小于一定宽度的所有图像?
Is there a way to delete all images in a folder which are less than a certain width via Windows Batch?
问:
我想编写一个简单的程序,将 Windows 聚光灯图像从它们所在的系统目录提取到一个文件夹中,在那里我可以更轻松地访问它们。到目前为止,我有这个:
@ECHO OFF
if not exist "%homedrive%%homepath%\Downloads\Spotlight" mkdir %homedrive%%homepath%\Downloads\Spotlight
xcopy /s %homedrive%%homepath%\AppData\Local\Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalState\Assets\ %homedrive%%homepath%\Downloads\Spotlight
ren %homedrive%%homepath%\Downloads\Spotlight\* *.jpg
它成功地将 spotlight 目录的内容复制到一个新文件夹中,然后重命名所有文件以使其成为 JPG。然而,也出现了一些杂项图标,以及“人像模式”聚光灯图像。我想通过检查输出文件夹中的每个 .jpg 来删除它们,看看它的宽度是否小于 1920 像素,如果是,则删除图像。
我去找 AI 试图解决我的问题,但失败了:
set "SpotlightFolder=%USERPROFILE%\Downloads\Spotlight"
:: Iterate over all .jpg files and delete those with width smaller than 1920 pixels
for %%F in ("%SpotlightFolder%\*.jpg") do (
for /f %%W in ('powershell -command "& {(Get-ImageDimensions '%%~F').Width}"') do set "Width=%%W"
if !Width! lss 1920 (
echo Deleting: %%~nxF
del "%%F"
) else (
echo Keeping: %%~nxF
)
)
:: PowerShell script to get image dimensions
<#
function Get-ImageDimensions {
param([string]$filePath)
$image = [System.Drawing.Image]::FromFile($filePath)
$width = $image.Width
$image.Dispose()
$width
}
#>
这将返回模糊的“命令的语法不正确”错误,并删除文件夹中的所有图像,而不考虑尺寸。 任何帮助将不胜感激。
答:
下面是一个 .bat 文件脚本,它将删除宽度小于 1000 的 .jpeg 文件。
编辑 PICDIR 并根据自己的喜好MIN_WIDTH值。当您对将删除正确的文件感到满意时,请从命令中删除 。-WhatIf
Remove-Item
SET "PICDIR=%USERPROFILE%\Pictures"
SET "MIN_WIDTH=1000"
pwsh -NoLogo -NoProfile -Command ^
"Add-Type -AssemblyName System.Drawing;" ^
"$PicDir = '"%PICDIR%"';" ^
"Get-ChildItem -File -Path $PicDir -Filter '*.jpeg' |" ^
"ForEach-Object {" ^
"$Image = [System.Drawing.Image]::FromFile($_.FullName);" ^
"if ($Image.Width -lt %MIN_WIDTH%) { $_ };" ^
"$Image.Dispose();" ^
"} |" ^
"Remove-Item -WhatIf;"
评论
-File
Get-ChildItem
-File
Add-Type
使用可能不是很有效,因为它实际上解码和加载了整个图像。可以使用 Shell COM 对象的 Folder.GetDetailsOf()
方法直接访问元数据,因此获取图像的宽度非常便宜。下面是一个简单的 PowerShell 脚本,用于执行所需的操作:Here's a simple PowerShell script to do what you want:System.Drawing.Image
$minWidth = 1920
$SpotlightFolder = "${env:USERPROFILE}\Downloads\Spotlight"
$widthColumnNum = 176 # or 165 or some other value, see below for details
$shell = New-Object -COMObject Shell.Application
$shellfolder = $shell.Namespace($SpotlightFolder)
Get-ChildItem -Filter *.jpg $SpotlightFolder | Where-Object {
$shellfile = $shellfolder.ParseName($_.Name)
$w = $shellfolder.GetDetailsOf($shellfile, $widthColumnNum)
[int]([regex]::Match($w, "\d+").Value) -lt $minWidth
} | Remove-Item -WhatIf
基本上,这将列出指定路径中的所有*.jpg文件,过滤小于传递给的文件。删除执行实际删除的选项Width
$minWidth
Remove-Item
-WhatIf
第 165 列是从这里取自的魔术,或者基于此的第 176 列。可以在 Shell32.Folder.GetDetailsOf(..,..) 中运行哪些选项中的 PowerShell 脚本,以查找系统上的实际值,以防它不同:
$objFolder = (New-Object -ComObject Shell.Application).Namespace('c:\')
for ($columnNumber = 0; $columnNumber -lt 500; ++$columnNumber)
{
$columnName = $objFolder.GetDetailsOf($objFolder.Items, $columnNumber)
if ($columnName)
{
Write-Output "$(([string]$columnNumber).PadLeft(3)) $columnName"
}
}
我已经在我的 PC 上测试了它并且它可以工作,图像宽度是预期的字段 176。当然,您也可以自动使用该方法来获取该神奇数字,但我在这里保持简单
有关元数据读取的详细信息,请查看
由于它使用 COM 对象,因此可以从支持 COM 对象的任何语言(例如 JS、VBS 或混合 VBS/混合 JS)调用它
评论
@%SystemRoot%\System32\xcopy.exe "%LocalAppData%\Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalState\Assets" "%UserProfile%\Downloads\Spotlight\"
@Ren "%UserProfile%\Downloads\Spotlight\*" *.jpg