Resize-Bitmap

По просьбе Артема Проничкина набросал скрипт для создания «превьюшек» изображений с максимальным размером стороны N, с сохранением пропорций. Для обработки картинок используются командлеты *-Bitmap из PowerShell Community Extensions.

$SourcePath = "C:\Картинки\*.*"
$DestPath = "C:\Output"
$MaxSize = 100

Foreach ($File in (dir $SourcePath))
{
    $Bitmap = $null
    $Bitmap = Import-Bitmap -Path $File -Verbose
    if ($Bitmap)
    {
        if ($Bitmap.Height -ge $Bitmap.Width)
        {
            $Bitmap = Resize-Bitmap -Bitmap $Bitmap -KeepAspectRatio -Height $MaxSize
        }
        else
        {
            $Bitmap = Resize-Bitmap -Bitmap $Bitmap -KeepAspectRatio -Width $MaxSize
        }
        Export-Bitmap -Bitmap $Bitmap -Path ($DestPath + "\" + $File.Name)
    }
    else
    {
        Write-Warning "Ну удалось обработать $File"
    }
}

А вообще эта задача решается с помощью бесплатной утилиты IrfanView, но мне было интересно поработать с *-Bitmap командлетами😉

комментариев 7 to “Resize-Bitmap”

  1. Артём Says:

    Спасибо! Есть, правда, ещё пара вопросов.

    1. Как бы делать две операции за один проход? Т.е. сейчас я должен запускать скрипт два раза, меняя размер генерируемой картинки и целевой путь. Понятно, что можно в один и тот же скрипт скопировать твой код два раза и поменять цифры🙂. Но наверняка есть смысл сделать это как-то более изящно.

    2. Как обрабатывать вложенные папки? Т.е. если если у меня есть подкаталоги A и B, и в каждом есть картинки, я хочу в результате получить A\Preview, A\Small, B\Preview, B\Small. Ну и так далее.

  2. Xaegr Says:

    1.
    Достаточно продублировать две строки
    $Bitmap = Resize-Bitmap …
    изменив размер, и присваивая другой переменной, например $Bitmap2 = Resize-Bitmap …
    Ну и продублировать строку с Export-Bitmap
    2. чтоб обрабатывать вложенные папки — достаточно приписать ключ -Recurse к командлету dir:
    Foreach ($File in (dir $SourcePath -Recurse))
    ЗЫ: Можно в почту — на https://xaegr.wordpress.com/about/ есть🙂

  3. Oleg Medvedev Says:

    А у меня есть скрипт, который меняет размер джипегов, тифов и прочих графических файлов.

    [reflection.assembly]::LoadWithPartialName(«System.Drawing»)

    $SizeLimit=1280
    $logfile=»resizelog.txt»
    $toresize=$args[0]

    if ([string]$toresize -eq «») {
    $toresize=@(‘n:\path1’, ‘n:\path2\’, ‘s:\path3’)
    }

    echo $toresize
    #Write-Host -NoNewLine («Press any key.»)
    #$null = $Host.UI.RawUI.ReadKey(«NoEcho,IncludeKeyDown»)
    #Write-Host «»

    $error.clear()

    Get-ChildItem -recurse $toresize -include *.jpg | foreach {
    $OldBitmap = new-object System.Drawing.Bitmap $_.FullName
    if ($error.count -ne 0) {
    $error | out-file $logfile -append -encoding default
    $error[($error.count-1)].TargetObject | out-file $logfile -append -encoding default
    echo $_>>$logfile
    $error.clear()
    }
    $LongSide=$OldBitmap.Width
    if ($OldBitmap.Width -lt $OldBitmap.Height) { $LongSide=$OldBitmap.Height }
    if ($LongSide -gt $SizeLimit) {
    if ($OldBitmap.Width -lt $OldBitmap.Height) {
    $newH=$SizeLimit
    $newW=[int]($OldBitmap.Width*$SizeLimit/$OldBitmap.Height)
    } else {
    $newW=$SizeLimit
    $newH=[int]($OldBitmap.Height*$newW/$OldBitmap.Width)
    }
    $NewBitmap = new-object System.Drawing.Bitmap $newW,$newH
    $g=[System.Drawing.Graphics]::FromImage($NewBitmap)
    $g.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
    $g.DrawImage($OldBitmap, 0, 0, $newW, $newH)

    $name=$_.DirectoryName+»\»+$_.name+».new»
    $NewBitmap.Save($name, ([system.drawing.imaging.imageformat]::jpeg))
    $NewBitmap.Dispose()
    $OldBitmap.Dispose()
    $n=get-childitem $name
    if ($n.length -ge $_.length) {
    Write-host -NoNewLine «+» # новый файл по размеру получился больше, чем старый
    $n.delete()
    } else {
    if ($n.Exists -and $_.Exists) {
    $name=$_.FullName
    $_.Delete()
    $n.MoveTo($name)
    echo ($Name + » » + $LongSide)
    }
    }

    } else {
    Write-host -NoNewLine «.»
    $OldBitmap.Dispose()
    }
    }

    Get-ChildItem -recurse $toresize -include *.bmp, *.tif, *.gif | foreach {
    $OldBitmap = new-object System.Drawing.Bitmap $_.FullName
    if ($error.count -ne 0) {
    $error | out-file $logfile -append -encoding default
    $error[($error.count-1)].TargetObject | out-file $logfile -append -encoding default
    $error.clear()
    }
    $LongSide=$OldBitmap.Width
    if ($OldBitmap.Width -lt $OldBitmap.Height) { $LongSide=$OldBitmap.Height }

    if ($LongSide -gt $SizeLimit) {
    if ($OldBitmap.Width -lt $OldBitmap.Height) {
    $newH=$SizeLimit
    $newW=[int]($OldBitmap.Width*$SizeLimit/$OldBitmap.Height)
    } else {
    $newW=$SizeLimit
    $newH=[int]($OldBitmap.Height*$newW/$OldBitmap.Width)
    }
    $NewBitmap = new-object System.Drawing.Bitmap $newW,$newH
    $g=[System.Drawing.Graphics]::FromImage($NewBitmap)
    $g.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
    $g.DrawImage($OldBitmap, 0, 0, $newW, $newH)

    $name=$_.DirectoryName+»\»+$_.name.substring(0, $_.name.indexof($_.extension))+».jpg»
    $NewBitmap.Save($name, ([system.drawing.imaging.imageformat]::jpeg))
    $NewBitmap.Dispose()
    $OldBitmap.Dispose()
    $n=get-childitem $name
    if ($n.length -ge $_.length) {
    $n.delete()
    Write-host -NoNewLine «+»
    } else {
    echo ($Name + » » + $LongSide)
    $_.Delete()
    }
    } else {
    $name=$_.DirectoryName+»\»+$_.name.substring(0, $_.name.indexof($_.extension))+».jpg»
    $OldBitmap.Save($name, ([system.drawing.imaging.imageformat]::jpeg))
    $OldBitmap.Dispose()
    $n=get-childitem $name
    if ($n.length -ge $_.length) {
    $n.delete()
    Write-host -NoNewLine «-»
    } else {
    echo ($Name + » » + $LongSide)
    $_.Delete()
    }
    }
    }

  4. Xaegr Says:

    2 Oleg Medvedev:
    Отличный скрипт🙂 Думаю эти командлеты как раз и используют System.Drawing🙂

    Кстати скрипт лучше было бы выложить на http://poshcode.org/ а сюда дать ссылку🙂 А то тут и форматирование съезжает, да и вообще комменты не слишком подходят для хранения скриптов🙂

  5. Oleg Medvedev Says:

    Извините.
    Вообще я стараюсь как можно меньше использовать какие-нибудь экстеншены и либрарии, с целью максимальной переносимости скриптов. Поэтому скрипты у меня, может быть, массивные.
    А похвастаться очень хочется.

  6. Xaegr Says:

    2 Oleg Medvedev: Безусловно это большой плюс. Но в комментариях скрипт найдет меньше народу чем на poshcode😉 Давайте вы запостите его туда, а я к посту приделаю ссылку на «вариант без использования внешних снапинов»🙂 А вообще если есть много чем похвастаться — может стоит завести блог?😉

  7. Oleg Medvedev Says:

    http://poshcode.org/621

    И насчёт похвастаться. Результатов у меня пока немного, всё больше затычки и подпорки для админских нужд, но вот сейчас пришлось писать реализацию smpp протокола.
    И в связи с этим к вам, как к гуру, вопрос:
    Есть ли в Powershell что-то типа strus паскалевского или record сишного?


Обсуждение закрыто.

%d такие блоггеры, как: