Skip to content

Instantly share code, notes, and snippets.

@scriptingstudio
Last active July 9, 2026 17:56
Show Gist options
  • Select an option

  • Save scriptingstudio/d711fb8d2235983da1a3132f8cc86dd3 to your computer and use it in GitHub Desktop.

Select an option

Save scriptingstudio/d711fb8d2235983da1a3132f8cc86dd3 to your computer and use it in GitHub Desktop.
A simple class that converts an image to an icon in PowerShell without losing image color data, unlike System.Drawing.Icon
class PngIconConverter {
static [bool] Convert([System.IO.Stream]$input_stream, [System.IO.Stream]$output_stream, [int]$size, [bool]$keep_aspect_ratio) {
$input_bit = [System.Drawing.Bitmap]::FromStream($input_stream)
if ($input_bit -eq $null) {return $false}
if ($size -lt 1) {$size = 32}
if ($keep_aspect_ratio) {
$width = $size
$height = $input_bit.Height / $input_bit.Width * $size
} else {
$width = $height = $size
}
$new_bit = [System.Drawing.Bitmap]::new($input_bit, [System.Drawing.Size]::new($width, $height))
if ($new_bit -eq $null) {return $false}
$mem_data = [System.IO.MemoryStream]::new()
$new_bit.Save($mem_data, [System.Drawing.Imaging.ImageFormat]::Png)
$icon_writer = [System.IO.BinaryWriter]::new($output_stream)
if ($output_stream -ne $null -and $icon_writer -ne $null) {
$icon_writer.Write([byte]0)
$icon_writer.Write([byte]0)
$icon_writer.Write([int16]1)
$icon_writer.Write([int16]1)
$icon_writer.Write([byte]$width)
$icon_writer.Write([byte]$height)
$icon_writer.Write([byte]0)
$icon_writer.Write([byte]0)
$icon_writer.Write([int16]0)
$icon_writer.Write([int16]32)
$icon_writer.Write([int]$mem_data.Length)
$icon_writer.Write([int](6 + 16))
$icon_writer.Write($mem_data.ToArray())
$icon_writer.Flush()
return $true
}
return $false
} # end
static [bool] Convert([string]$input_image, [string]$output_icon, [int]$size, [bool]$keep_aspect_ratio) {
[System.IO.Stream]$input_stream = [System.IO.FileStream]::new($input_image, [System.IO.FileMode]::Open)
[System.IO.Stream]$output_stream = [System.IO.FileStream]::new($output_icon, [System.IO.FileMode]::OpenOrCreate)
if ($size -lt 1) {$size = 32}
$result = [PngIconConverter]::Convert($input_stream, $output_stream, $size, $keep_aspect_ratio)
$input_stream.Close()
$output_stream.Close()
return $result
} # end
} # end PngIconConverter
#### EXAMPLE ####
Add-Type -AssemblyName System.Drawing
$tmp = "$env:TEMP\psicon.png"
$iconsource = 'C:\windows\system32\WindowsPowerShell\v1.0\PowerShell.exe'
$iconFile = '.\psicon.ico'
[System.Drawing.Icon]::ExtractAssociatedIcon($iconsource).ToBitMap().Save($tmp)
[PngIconConverter]::Convert($tmp,$iconFile,32,$true)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment