Skip to content

Instantly share code, notes, and snippets.

@scriptingstudio
Last active August 3, 2026 06:32
Show Gist options
  • Select an option

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

Select an option

Save scriptingstudio/e9bfdf2f2088089226f23c388791c401 to your computer and use it in GitHub Desktop.
ICO to PNG converter demo for Windows PowerShell
function Convert-IcoToPng ([string]$icofile) {
# Runtime validation
if ($PSVersionTable.PSEdition -eq 'Core') {return}
if (-not $icofile -or -not (Test-Path $icofile)) {return}
# ICO validation
$signature = Get-Content -Path $icofile -Encoding Byte -TotalCount 6 -ErrorAction 0
if (([System.BitConverter]::ToInt32(($signature[0..3]),0)) -ne 0x10000) {return}
if (([System.BitConverter]::ToInt16(($signature[4,5]),0)) -gt 1) {return} # single-size
Add-Type -AssemblyName System.Runtime.WindowsRuntime
$runtimeMethods = [System.WindowsRuntimeSystemExtensions].GetMethods()
$asTaskGeneric = ($runtimeMethods | Where-Object {$_.Name -eq 'AsTask' -and $_.GetParameters().Count -eq 1 -and $_.GetParameters()[0].ParameterType.Name -eq 'IAsyncOperation`1' })[0]
function AwaitOperation ($WinRtTask, $ResultType) {
$asTaskSpecific = $asTaskGeneric.MakeGenericMethod($ResultType)
$netTask = $asTaskSpecific.Invoke($null, @($WinRtTask))
$null = $netTask.Wait()
$netTask.Result
}
$asTask = ($runtimeMethods | Where-Object {$_.Name -eq 'AsTask' -and $_.GetParameters().Count -eq 1 -and $_.GetParameters()[0].ParameterType.Name -eq 'IAsyncAction' })[0]
function AwaitAction ($WinRtTask) {
$netTask = $asTask.Invoke($null, @($WinRtTask))
$null = $netTask.Wait()
}
# Reference WinRT assemblies
$null = [Windows.Storage.StorageFile, Windows.Storage, ContentType=WindowsRuntime]
$null = [Windows.Graphics.Imaging.BitmapDecoder, Windows.Graphics, ContentType=WindowsRuntime]
$file = Resolve-Path -LiteralPath $icofile
$inputFile = AwaitOperation ([Windows.Storage.StorageFile]::GetFileFromPathAsync($file)) ([Windows.Storage.StorageFile])
$inputFolder = AwaitOperation ($inputFile.GetParentAsync()) ([Windows.Storage.StorageFolder])
$inputStream = AwaitOperation ($inputFile.OpenReadAsync()) ([Windows.Storage.Streams.IRandomAccessStreamWithContentType])
$decoder = AwaitOperation ([Windows.Graphics.Imaging.BitmapDecoder]::CreateAsync($inputStream)) ([Windows.Graphics.Imaging.BitmapDecoder])
$bitmap = AwaitOperation $decoder.GetSoftwareBitmapAsync() ([Windows.Graphics.Imaging.SoftwareBitmap])
# Write SoftwareBitmap to output file
$outputFileName = $inputFile.Name -replace ($inputFile.FileType + "$"), ".png"
$outputFile = AwaitOperation ($inputFolder.CreateFileAsync($outputFileName, [Windows.Storage.CreationCollisionOption]::ReplaceExisting)) ([Windows.Storage.StorageFile])
$outputStream = AwaitOperation ($outputFile.OpenAsync([Windows.Storage.FileAccessMode]::ReadWrite)) ([Windows.Storage.Streams.IRandomAccessStream])
$encoder = AwaitOperation ([Windows.Graphics.Imaging.BitmapEncoder]::CreateAsync([Windows.Graphics.Imaging.BitmapEncoder]::PngEncoderId, $outputStream)) ([Windows.Graphics.Imaging.BitmapEncoder])
$encoder.SetSoftwareBitmap($bitmap)
$encoder.IsThumbnailGenerated = $false # PNG encoder doesn't like the thumbnail generation
# Finishing & cleanup
AwaitAction $encoder.FlushAsync()
if ($bitmap) {$bitmap.Dispose()}
if ($inputStream) {$inputStream.Dispose()}
if ($outputStream) {$outputStream.Dispose()}
} # END Convert-IcoToPng
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment