Powershell - 按尺寸对照片进行排序的脚本,有评估数字的问题'

时间:2014-05-07 09:39:21

标签: string image powershell integer dimensions

我正在尝试编写一个Powershell脚本,根据图像宽度将数千张照片分类到各个文件夹中。

我想:

  • 300px以下的照片被归类为小型。
  • 301px和799px之间的照片被归类为中等。
  • 800px及以上的照片被归为大型。

我发现了我正在使用的这个很棒的功能: 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搜索结果,但我找不到答案。

有人可以帮忙吗?

3 个答案:

答案 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","");

摆脱白色空间。