param([switch]$Replace)
$ErrorActionPreference = 'Stop'
Add-Type -AssemblyName System.Drawing
$source = Join-Path $PSScriptRoot 'xfesystem-icon.png'
$pngDirectory = Join-Path $PSScriptRoot 'png'
$sizes = @(16, 24, 32, 48, 64, 128, 256, 512)
$ico = Join-Path $PSScriptRoot 'xfesystem.ico'
$destinations = @($ico) + @($sizes | ForEach-Object { Join-Path $pngDirectory "xfesystem-$_.png" })
if (!$Replace) {
foreach ($destination in $destinations) {
if (Test-Path -LiteralPath $destination) { throw "Export exists: $destination. Use -Replace to regenerate exports." }
}
}
New-Item -ItemType Directory -Path $pngDirectory -Force | Out-Null
$image = [Drawing.Bitmap]::new($source)
try {
foreach ($size in $sizes) {
$bitmap = [Drawing.Bitmap]::new($size, $size, [Drawing.Imaging.PixelFormat]::Format32bppArgb)
try {
$graphics = [Drawing.Graphics]::FromImage($bitmap)
try {
$graphics.Clear([Drawing.Color]::Transparent)
$graphics.CompositingMode = [Drawing.Drawing2D.CompositingMode]::SourceCopy
$graphics.InterpolationMode = [Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
$graphics.PixelOffsetMode = [Drawing.Drawing2D.PixelOffsetMode]::HighQuality
$graphics.DrawImage($image, [Drawing.Rectangle]::new(0, 0, $size, $size))
} finally { $graphics.Dispose() }
$bitmap.Save((Join-Path $pngDirectory "xfesystem-$size.png"), [Drawing.Imaging.ImageFormat]::Png)
} finally { $bitmap.Dispose() }
}
} finally { $image.Dispose() }
# Windows ICO container, with lossless PNG payloads including their alpha.
$icoSizes = @($sizes | Where-Object { $_ -le 256 })
$payloads = @($icoSizes | ForEach-Object { ,([IO.File]::ReadAllBytes((Join-Path $pngDirectory "xfesystem-$_.png"))) })
$stream = [IO.File]::Open($ico, [IO.FileMode]::Create, [IO.FileAccess]::Write)
$writer = [IO.BinaryWriter]::new($stream)
try {
$writer.Write([uint16]0)
$writer.Write([uint16]1)
$writer.Write([uint16]$icoSizes.Count)
$offset = 6 + 16 * $icoSizes.Count
for ($index = 0; $index -lt $icoSizes.Count; $index++) {
$size = $icoSizes[$index]
$dimension = if ($size -eq 256) { 0 } else { $size }
$writer.Write([byte]$dimension)
$writer.Write([byte]$dimension)
$writer.Write([byte]0)
$writer.Write([byte]0)
$writer.Write([uint16]1)
$writer.Write([uint16]32)
$writer.Write([uint32]$payloads[$index].Length)
$writer.Write([uint32]$offset)
$offset += $payloads[$index].Length
}
foreach ($payload in $payloads) { $writer.Write([byte[]]$payload) }
} finally { $writer.Dispose(); $stream.Dispose() }
Write-Host "PNG sizes: $($sizes -join ', '); Windows icon: $ico"
param([switch]$Replace)
$ErrorActionPreference = 'Stop'
Add-Type -AssemblyName System.Drawing
$source = Join-Path $PSScriptRoot 'xfesystem-icon.png'
$pngDirectory = Join-Path $PSScriptRoot 'png'
$sizes = @(16, 24, 32, 48, 64, 128, 256, 512)
$ico = Join-Path $PSScriptRoot 'xfesystem.ico'
$destinations = @($ico) + @($sizes | ForEach-Object { Join-Path $pngDirectory "xfesystem-$_.png" })
if (!$Replace) {
foreach ($destination in $destinations) {
if (Test-Path -LiteralPath $destination) { throw "Export exists: $destination. Use -Replace to regenerate exports." }
}
}
New-Item -ItemType Directory -Path $pngDirectory -Force | Out-Null
$image = [Drawing.Bitmap]::new($source)
try {
foreach ($size in $sizes) {
$bitmap = [Drawing.Bitmap]::new($size, $size, [Drawing.Imaging.PixelFormat]::Format32bppArgb)
try {
$graphics = [Drawing.Graphics]::FromImage($bitmap)
try {
$graphics.Clear([Drawing.Color]::Transparent)
$graphics.CompositingMode = [Drawing.Drawing2D.CompositingMode]::SourceCopy
$graphics.InterpolationMode = [Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
$graphics.PixelOffsetMode = [Drawing.Drawing2D.PixelOffsetMode]::HighQuality
$graphics.DrawImage($image, [Drawing.Rectangle]::new(0, 0, $size, $size))
} finally { $graphics.Dispose() }
$bitmap.Save((Join-Path $pngDirectory "xfesystem-$size.png"), [Drawing.Imaging.ImageFormat]::Png)
} finally { $bitmap.Dispose() }
}
} finally { $image.Dispose() }
# Windows ICO container, with lossless PNG payloads including their alpha.
$icoSizes = @($sizes | Where-Object { $_ -le 256 })
$payloads = @($icoSizes | ForEach-Object { ,([IO.File]::ReadAllBytes((Join-Path $pngDirectory "xfesystem-$_.png"))) })
$stream = [IO.File]::Open($ico, [IO.FileMode]::Create, [IO.FileAccess]::Write)
$writer = [IO.BinaryWriter]::new($stream)
try {
$writer.Write([uint16]0)
$writer.Write([uint16]1)
$writer.Write([uint16]$icoSizes.Count)
$offset = 6 + 16 * $icoSizes.Count
for ($index = 0; $index -lt $icoSizes.Count; $index++) {
$size = $icoSizes[$index]
$dimension = if ($size -eq 256) { 0 } else { $size }
$writer.Write([byte]$dimension)
$writer.Write([byte]$dimension)
$writer.Write([byte]0)
$writer.Write([byte]0)
$writer.Write([uint16]1)
$writer.Write([uint16]32)
$writer.Write([uint32]$payloads[$index].Length)
$writer.Write([uint32]$offset)
$offset += $payloads[$index].Length
}
foreach ($payload in $payloads) { $writer.Write([byte[]]$payload) }
} finally { $writer.Dispose(); $stream.Dispose() }
Write-Host "PNG sizes: $($sizes -join ', '); Windows icon: $ico"