Last active
August 3, 2026 06:32
-
-
Save scriptingstudio/e9bfdf2f2088089226f23c388791c401 to your computer and use it in GitHub Desktop.
ICO to PNG converter demo for Windows PowerShell
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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