我正在尝试编写一个Powershell脚本,根据图像宽度将数千张照片分类到各个文件夹中。
我想:
我发现了我正在使用的这个很棒的功能: MS technet article
问题是Powershell似乎在评估超过1000px宽的数字/图像时遇到了问题。
我的代码在这里(当然不是很漂亮/精简):
Function Get-FileMetaData
{
Param([string[]]$folder)
foreach($sFolder in $folder)
{
$a = 0
$objShell = New-Object -ComObject Shell.Application
$objFolder = $objShell.namespace($sFolder)
foreach ($File in $objFolder.items())
{
$FileMetaData = New-Object PSOBJECT
for ($a ; $a -le 266; $a++)
{
if($objFolder.getDetailsOf($File, $a))
{
$hash += @{$($objFolder.getDetailsOf($objFolder.items, $a)) =
$($objFolder.getDetailsOf($File, $a)) }
$FileMetaData | Add-Member $hash
$hash.clear()
} #end if
} #end for
$a=0
$FileMetaData
} #end foreach $file
} #end foreach $sfolder
} #end Get-FileMetaData
$photodir="C:\photos\"
Get-FileMetaData -folder $photodir | select path,dimensions |
ForEach-Object -Process {
if ($_.dimensions -ne $null){
$filename=$_.path;
$dimensions=$($_.dimensions);
$dimensions_split=$dimensions.split();
$dimensions_width=$($dimensions_split[0]);
if ($dimensions_width -gt "799"){"$filename is $dimensions_width so is large";"---";}
if (($dimensions_width -lt "800") -and ($dimensions_width -gt "300")){"$filename is $dimensions_width so is medium";"---";}
if ($dimensions_width -lt "300"){"$filename is $dimensions_width so is small";"---";}
这给出了结果:
C:\photos\logo1024x1024.jpg is 1024 so is small
---
C:\photos\logo128x128.jpg is 128 so is small
---
C:\photos\logo1600x1600.jpg is 1600 so is small
---
C:\photos\logo1920x1080.jpg is 1920 so is small
---
C:\photos\logo512x512.jpg is 512 so is medium
---
C:\photos\logo960x960.jpg is 960 so is large
---
所以我想也许这是一个问题,因为它们是字符串。如果我强迫它们成为整数怎么办?Powershell可以正确评估它们:
if ([int]$dimensions_width -gt 800){"$filename is $dimensions_width so is large";"---";}
这会出错:
Cannot convert value "1024" to type "System.Int32". Error: "Input string was
not in a correct format."
At C:\scripts\sort_photos_sm_md_lg.ps1:39
char:9
+ if ([int]$dimensions_width -gt 799){"$filename is $dimensions_width so
is la ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastFromStringToInteger
这对我来说没有意义,因为1024对我来说看起来像一个整数?
如果我这样做,Powershell喜欢语法,但仍然无法正确评估它:
if (($dimensions_width -as [int]) -gt 799){"$filename is $dimensions_width so is large";"---";}
尽管经历了几页Google搜索结果,但我找不到答案。
有人可以帮忙吗?
答案 0 :(得分:2)
试试这个:
$photodir= "C:\photos"
Get-FileMetaData -folder $photodir | select percorso,dimensioni |
ForEach-Object -Process {
if ($_.dimensioni -ne $null)
{
$filename=$_.percorso;
$dimensions=$($_.dimensioni);
$dimensions_width= [int](-join ((( $dimensions -split ' ' )[0]).ToCharArray() )[1..4])
}
switch ($dimensions_width)
{
{$_ -gt 799} {"$filename is $dimensions_width so is large";"---";break}
{$_ -lt 800 -and $dimensions_width -gt 300} {"$filename is $dimensions_width so is medium";"---";break}
default {"$filename is $dimensions_width so is small"; "---";break}
}
}
@Raf提到的问题在拆分后是非法字符,但不是空格,而是[char][int]8234
值不受trim()
方法影响。
答案 1 :(得分:1)
至于解决方法,GDI+ can be used来阅读各种各样的文件元数据。只需打开文件Drawing.Bitmap
即可提供尺寸。像这样,
# Load the drawing assembly
add-type -assemblyname System.Drawing
# Open the image
$img = new-object Drawing.Bitmap("C:\MyBigImage.jpg")
# Print dimensions
$("w:{0} h:{1}" -f $img.Width, $img.Height)
w:3264 h:2448 # Quite big a picture
# Don't forget to dispose the bitmap
$img.Dispose()
答案 2 :(得分:0)
您最有可能在$dimensions_width
内领导或追踪非法字符。您可以通过回显$dimensions_width.Length
来验证它,这是字符串中的字符数:
...
$dimensions_width=$($dimensions_split[0]);
Write-Host ("Width " + $dimensions_width + ",Length " + $dimensions_width.Length)
if ($dimensions_width -gt "799")....
....
如果在1024上你得到长度大于4那么这就是它。试试
$dimensions_width=$($dimensions_split[0].Trim() -replace "`n|`r|`t","");
摆脱白色空间。