Использование Powershell .NET .DrawImage в System.Drawing - PullRequest
2 голосов
/ 05 марта 2019

Я создаю инструмент, который автоматизирует кадрирование и позиционирование без изменения размера изображения в другое изображение.Я нашел this в документах Microsoft для .NET, но я не могу понять, как реализовать в моем коде.Что я получаю до сих пор:

Bernd_L.png Bernd_L.png
Steve Steve.png

с этим сценарием:

$Username="Bernd_L"
$Uuid=$(ConvertFrom-JSON -InputObject ($(Invoke-webrequest -URI "https://api.mojang.com/users/profiles/minecraft/$($Username)").Content)).id
$Base64Skin=(Invoke-webrequest -URI $(ConvertFrom-JSON -InputObject ($([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($($(ConvertFrom-JSON -InputObject ($(Invoke-webrequest -URI "https://sessionserver.mojang.com/session/minecraft/profile/$($Uuid)").Content)).properties.value)))))).textures.skin.url).Content
[IO.File]::WriteAllBytes("$pwd\$Username.png", $Base64Skin)

Мне было интересно, смогу ли я обрезать прямоугольник 8x8 пикселей с координатами 8,0 1.png и вставить его поверх Steve.png с координатами 8,8, чтобыв конце вывод будет выглядеть так:

output.png output.png

Что я должен использовать .Net в powershell изначально?Кроме того, есть ли хорошее место, чтобы найти примеры System.Drawing в сценариях powershell?

EDIT
Спасибо @Caramiriel за ссылку.Теперь я могу полностью обрезать изображение с помощью этого сценария:

Add-Type -AssemblyName System.Drawing

$Username="Bernd_L"
$Uuid=$(ConvertFrom-JSON -InputObject ($(Invoke-webrequest -URI "https://api.mojang.com/users/profiles/minecraft/$($Username)").Content)).id
$Base64Skin=(Invoke-webrequest -URI $(ConvertFrom-JSON -InputObject ($([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($($(ConvertFrom-JSON -InputObject ($(Invoke-webrequest -URI "https://sessionserver.mojang.com/session/minecraft/profile/$($Uuid)").Content)).properties.value)))))).textures.skin.url).Content
[IO.File]::WriteAllBytes("$pwd\$Username.png", $Base64Skin)

$destRect = new-object Drawing.Rectangle 8, 0, 8, 8
$srcRect = new-object Drawing.Rectangle 0, 8, 8, 8
$src=[System.Drawing.Image]::FromFile("$pwd\$Username.png")
$bmp=new-object System.Drawing.Bitmap 64,64
$graphics=[System.Drawing.Graphics]::FromImage($bmp)
$units = [System.Drawing.GraphicsUnit]::Pixel
$graphics.DrawImage($src, $destRect, $srcRect, $units)
$graphics.Dispose()
$bmp.Save("$pwd\output.png")

Если есть более компактный / элегантный способ сделать это, я действительно хотел бы знать это!

1 Ответ

1 голос
/ 05 марта 2019

Как предложено @ Mathias R. Jessen Я использовал функцию, чтобы она выглядела более элегантно: Add-Type -AssemblyName System.Drawing

$Username="Steve"
$Uuid=$(ConvertFrom-JSON -InputObject ($(Invoke-webrequest -URI "https://api.mojang.com/users/profiles/minecraft/$($Username)").Content)).id
$Base64Skin=(Invoke-webrequest -URI $(ConvertFrom-JSON -InputObject ($([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($($(ConvertFrom-JSON -InputObject ($(Invoke-webrequest -URI "https://sessionserver.mojang.com/session/minecraft/profile/$($Uuid)").Content)).properties.value)))))).textures.skin.url).Content
[IO.File]::WriteAllBytes("$pwd\$Username.png", $Base64Skin)


$bmp=new-object System.Drawing.Bitmap 64,64
$graphics=[System.Drawing.Graphics]::FromImage($bmp)
$src=[System.Drawing.Image]::FromFile("$pwd\$Username.png")
$units = [System.Drawing.GraphicsUnit]::Pixel

function DrawCroppedImage {
    param( [int]$srcX, [int]$srcY, [int]$srcWidth, [int]$srcHeight, [int]$destX, [int]$destY, [int]$destWidth, [int]$destHeight )
    $destRect = new-object Drawing.Rectangle $destX, $destY, $destWidth, $destHeight
    $srcRect = new-object Drawing.Rectangle $srcX, $srcY, $srcWidth, $srcHeight
    $graphics.DrawImage($src, $destRect, $srcRect, $units)
}

DrawCroppedImage 8 0 8 8 8 0 8 8

$graphics.Dispose()
$bmp.Save("$pwd\1.png")

Так что я могу повторить ее/ out переписать весь код снова для каждого отдельного урожая.Я хотел бы добавить тот факт, что если вы масштабируете его (последние два целых числа = 16), но вы хотите сделать это без какой-либо интерполяции, вы можете использовать ту же функцию, но с еще двумя строками:

function DrawCroppedImage {
    param( [int]$SrcX, [int]$SrcY, [int]$SrcWidth, [int]$SrcHeight, [int]$DestX, [int]$DestY, [int]$DestWidth, [int]$DestHeight )
    $DestRect = new-object Drawing.Rectangle $DestX, $DestY, $DestWidth, $DestHeight
    $SrcRect = new-object Drawing.Rectangle $SrcX, $SrcY, $SrcWidth, $SrcHeight
    $graphics.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::NearestNeighbor
    $graphics.PixelOffsetMode = [System.Drawing.Drawing2D.PixelOffsetMode]::Half
    $graphics.DrawImage($Src, $DestRect, $SrcRect, $Units)
    $graphics.Dispose()
}

Найденочерез эту тему

...