Home > Software engineering >  Resize a Byte Array image in PowerShell
Resize a Byte Array image in PowerShell

Time:12-21

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 :)

CodePudding user response:

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.

CodePudding user response:

@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()
 }
}
  • Related