Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resize a Byte Array image in PowerShell

I'm trying to resize an image in PowerShell without saving a temporary file and then save it to Active Directory.

I'm getting a Byte Array from a database (I have no control over what is sent to me) and I'm able to save this as a file easily like this:

[System.Io.File]::WriteAllBytes("C:\PathToFile\img.jpg", $PhotoArray)

What I need to do is resize the image and then update the thumbnail image in Active Directory. I'm able to do this with the original file as it's already given to me as a Byte Array like this:

Set-ADUser -Identity $UserName -Replace @{thumbnailPhoto=$Photo} -Server $AdServerName

I can resize the image to make it smaller using this code:

$Photo_MemoryStream = new-object System.IO.MemoryStream(,$PhotoAsByteArray)
$quality = 75
$bmp = [system.drawing.Image]::FromStream($Photo_MemoryStream)
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[decimal]$canvasWidth = 100.0
[decimal]$canvasHeight = 100.0

$myEncoder = [System.Drawing.Imaging.Encoder]::Quality
$encoderParams = New-Object System.Drawing.Imaging.EncoderParameters(1)
$encoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter($myEncoder, $quality)
$myImageCodecInfo = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders()|where {$_.MimeType -eq 'image/jpeg'}

$ratioX = $canvasWidth / $bmp.Width;
$ratioY = $canvasHeight / $bmp.Height;
$ratio = $ratioY
if($ratioX -le $ratioY){
  $ratio = $ratioX
}

$newWidth = [int] ($bmp.Width*$ratio)
$newHeight = [int] ($bmp.Height*$ratio)
$bmpResized = New-Object System.Drawing.Bitmap($newWidth, $newHeight)

$graph = [System.Drawing.Graphics]::FromImage($bmpResized)
$graph.Clear([System.Drawing.Color]::White)
$graph.DrawImage($bmp,0,0 , $newWidth, $newHeight)

$bmpResized.Save("C:\PathToFile\img.jpg",$myImageCodecInfo, $($encoderParams))

How do I convert $bmpResized into a Byte Array so I can insert it into Active Directory? I'm sure this should be easy, but I've spent a long time trying to work out how to convert it into a Byte Array and failed!

I'm hoping someone out there has the magic answer I'm looking for :)

like image 359
Blind Trevor Avatar asked Feb 14 '26 20:02

Blind Trevor


2 Answers

I've done this exact thing in C#. It's really the same in PowerShell since you're using .NET classes to do it.

You'd still use .Save, but to a MemoryStream, then use MemoryStream.ToArray(), like this:

$stream = New-Object System.IO.MemoryStream
$bmpResized.Save($stream, [System.Drawing.Imaging.ImageFormat]::Jpeg)
$byteArray = $stream.ToArray()

This assumes you want all your images in JPEG format.

like image 91
Gabriel Luci Avatar answered Feb 16 '26 21:02

Gabriel Luci


@Theo already gave answer in OP for dealing with file. Below is an example of saving resized photo to MemoryStream:

See (C# example): Convert a bitmap into a byte array

try {
 $resizedStream = New-Object System.IO.MemoryStream
 $bmpResized.Save($resizedStream, ,$myImageCodecInfo, $encoderParams)
 $resizedPhotoByteArray = $resizedStream.ToArray()
}
finally {
 if ($null -ne $resizedStream) {
  $resizedStream.Dispose()
 }
}
like image 44
dugas Avatar answered Feb 16 '26 22:02

dugas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!