2010-06-02 6 views
9

Меня интересует поиск файлов по пользовательским свойствам. Например, я хочу найти все JPEG-изображения с определенными размерами. Что-то похоже наИнтеллектуальный поиск изображений через Powershell

Get-ChildItem -Path C:\ -Filter *.jpg -Recursive | where-object { $_.Dimension -eq '1024x768' } 

Я подозреваю, что речь идет об использовании System.Drawing. Как это можно сделать? Заранее спасибо

ответ

12

Это на самом деле очень легко сделать, и ваше шестое чувство о System.Drawing было на самом деле правильно:

Add-Type -Assembly System.Drawing 

$input | ForEach-Object { [Drawing.Image]::FromFile($_) } 

Сохранить, что, как Get-Image.ps1 где-то на своем пути, а затем вы можете использовать его.

Другим вариантом было бы добавить следующее к $profile:

Add-Type -Assembly System.Drawing 

function Get-Image { 
    $input | ForEach-Object { [Drawing.Image]::FromFile($_) } 
} 

, который работает в значительной степени то же самое. Конечно, добавьте интересные вещи, такие как документация или так, как вы сочтете нужным.

Вы можете затем использовать его следующим образом:

gci -inc *.jpg -rec | Get-Image | ? { $_.Width -eq 1024 -and $_.Height -eq 768 } 

Обратите внимание, что вы должны расположить объекты, созданные таким образом, после их использования.

Конечно, вы можете добавить пользовательский Dimension свойство, чтобы вы могли фильтровать, что:

function Get-Image { 
    $input | 
     ForEach-Object { [Drawing.Image]::FromFile($_) } | 
     ForEach-Object { 
      $_ | Add-Member -PassThru NoteProperty Dimension ('{0}x{1}' -f $_.Width,$_.Height) 
     } 
} 
+1

Вы ответите, что изображение должно быть удалено после завершения задачи? Просто для обучения других сценаристов. Утилизировать метод часто пропускают ... – stej

+1

@stej: Eep, хорошо. Любой способ сделать это правильно или автоматически, за исключением добавления '% {$ _. Dispose()}' в конец конвейера? – Joey

+0

Я не думаю, что есть лучший способ, чем делать это вручную, как вы предлагаете. Или дождитесь окончания сессии Posh. Тем не менее, я обычно открываю консоль Posh после входа в систему и закрытия ее до выхода из системы, так что это не идеально. Try/Наконец-то может помочь, но это накладные расходы. Я думаю, что достаточно записки и пусть остальное читатели;) – stej

3

Вот альтернативная реализация, как (почти) однострочника:

Add-Type -Assembly System.Drawing 

Get-ChildItem -Path C:\ -Filter *.jpg -Recursive | ForEach-Object { [System.Drawing.Image]::FromFile($_.FullName) } | Where-Object { $_.Width -eq 1024 -and $_.Height -eq 768 } 

Если вы потребуется выполнить эту команду более одного раза, вместо этого я бы порекомендовал Johannes' more complete solution.