Initial commit
This commit is contained in:
145
scripts/gen-icons.ps1
Normal file
145
scripts/gen-icons.ps1
Normal file
@@ -0,0 +1,145 @@
|
||||
Add-Type -AssemblyName System.Drawing
|
||||
|
||||
$resourcesDir = Join-Path $PSScriptRoot "..\resources"
|
||||
$resourcesDir = (Resolve-Path $resourcesDir).Path
|
||||
|
||||
function New-AppIcon([int]$size, [string]$path) {
|
||||
$bmp = New-Object System.Drawing.Bitmap $size, $size
|
||||
$g = [System.Drawing.Graphics]::FromImage($bmp)
|
||||
$g.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::AntiAlias
|
||||
$g.Clear([System.Drawing.Color]::Transparent)
|
||||
|
||||
# Rounded square background with gradient (blue → teal)
|
||||
$rect = New-Object System.Drawing.RectangleF (0, 0, $size, $size)
|
||||
$path1 = New-Object System.Drawing.Drawing2D.GraphicsPath
|
||||
$r = $size * 0.22
|
||||
$path1.AddArc($rect.X, $rect.Y, $r * 2, $r * 2, 180, 90)
|
||||
$path1.AddArc($rect.X + $rect.Width - $r * 2, $rect.Y, $r * 2, $r * 2, 270, 90)
|
||||
$path1.AddArc($rect.X + $rect.Width - $r * 2, $rect.Y + $rect.Height - $r * 2, $r * 2, $r * 2, 0, 90)
|
||||
$path1.AddArc($rect.X, $rect.Y + $rect.Height - $r * 2, $r * 2, $r * 2, 90, 90)
|
||||
$path1.CloseFigure()
|
||||
|
||||
$color1 = [System.Drawing.Color]::FromArgb(255, 91, 141, 239)
|
||||
$color2 = [System.Drawing.Color]::FromArgb(255, 41, 199, 184)
|
||||
$brush = New-Object System.Drawing.Drawing2D.LinearGradientBrush $rect, $color1, $color2, 45
|
||||
$g.FillPath($brush, $path1)
|
||||
|
||||
# Inner heartbeat / activity line
|
||||
$pen = New-Object System.Drawing.Pen ([System.Drawing.Color]::White), ($size * 0.07)
|
||||
$pen.LineJoin = [System.Drawing.Drawing2D.LineJoin]::Round
|
||||
$pen.StartCap = [System.Drawing.Drawing2D.LineCap]::Round
|
||||
$pen.EndCap = [System.Drawing.Drawing2D.LineCap]::Round
|
||||
$mid = [single]($size / 2.0)
|
||||
$points = [System.Drawing.PointF[]]@(
|
||||
[System.Drawing.PointF]::new([single]($size * 0.22), $mid),
|
||||
[System.Drawing.PointF]::new([single]($size * 0.36), $mid),
|
||||
[System.Drawing.PointF]::new([single]($size * 0.44), [single]($mid - $size * 0.22)),
|
||||
[System.Drawing.PointF]::new([single]($size * 0.56), [single]($mid + $size * 0.22)),
|
||||
[System.Drawing.PointF]::new([single]($size * 0.64), $mid),
|
||||
[System.Drawing.PointF]::new([single]($size * 0.78), $mid)
|
||||
)
|
||||
$g.DrawLines($pen, $points)
|
||||
|
||||
$pen.Dispose()
|
||||
$brush.Dispose()
|
||||
$path1.Dispose()
|
||||
$g.Dispose()
|
||||
$bmp.Save($path, [System.Drawing.Imaging.ImageFormat]::Png)
|
||||
$bmp.Dispose()
|
||||
}
|
||||
|
||||
function New-TrayIcon([int]$size, [string]$path) {
|
||||
$bmp = New-Object System.Drawing.Bitmap $size, $size
|
||||
$g = [System.Drawing.Graphics]::FromImage($bmp)
|
||||
$g.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::AntiAlias
|
||||
$g.Clear([System.Drawing.Color]::Transparent)
|
||||
|
||||
# Monochrome white heartbeat line
|
||||
$pen = New-Object System.Drawing.Pen ([System.Drawing.Color]::White), ($size * 0.13)
|
||||
$pen.LineJoin = [System.Drawing.Drawing2D.LineJoin]::Round
|
||||
$pen.StartCap = [System.Drawing.Drawing2D.LineCap]::Round
|
||||
$pen.EndCap = [System.Drawing.Drawing2D.LineCap]::Round
|
||||
$mid = [single]($size / 2.0)
|
||||
$points = [System.Drawing.PointF[]]@(
|
||||
[System.Drawing.PointF]::new([single]($size * 0.08), $mid),
|
||||
[System.Drawing.PointF]::new([single]($size * 0.30), $mid),
|
||||
[System.Drawing.PointF]::new([single]($size * 0.40), [single]($mid - $size * 0.30)),
|
||||
[System.Drawing.PointF]::new([single]($size * 0.55), [single]($mid + $size * 0.30)),
|
||||
[System.Drawing.PointF]::new([single]($size * 0.65), $mid),
|
||||
[System.Drawing.PointF]::new([single]($size * 0.92), $mid)
|
||||
)
|
||||
$g.DrawLines($pen, $points)
|
||||
$pen.Dispose()
|
||||
$g.Dispose()
|
||||
$bmp.Save($path, [System.Drawing.Imaging.ImageFormat]::Png)
|
||||
$bmp.Dispose()
|
||||
}
|
||||
|
||||
# Write tray PNGs (16, 32)
|
||||
New-TrayIcon 16 (Join-Path $resourcesDir "tray.png")
|
||||
New-TrayIcon 32 (Join-Path $resourcesDir "tray@2x.png")
|
||||
|
||||
# Write app PNGs (multiple sizes for ICO assembly)
|
||||
$sizes = @(16, 24, 32, 48, 64, 128, 256)
|
||||
$pngPaths = @()
|
||||
foreach ($s in $sizes) {
|
||||
$p = Join-Path $resourcesDir ("icon-$s.png")
|
||||
New-AppIcon $s $p
|
||||
$pngPaths += $p
|
||||
}
|
||||
|
||||
# Assemble multi-resolution ICO
|
||||
function Write-Ico([string[]]$pngFiles, [string]$icoPath) {
|
||||
$entries = @()
|
||||
$data = New-Object System.IO.MemoryStream
|
||||
foreach ($pf in $pngFiles) {
|
||||
$bytes = [System.IO.File]::ReadAllBytes($pf)
|
||||
$bmp = [System.Drawing.Image]::FromFile($pf)
|
||||
$entries += [pscustomobject]@{
|
||||
Width = $bmp.Width
|
||||
Height = $bmp.Height
|
||||
Size = $bytes.Length
|
||||
Bytes = $bytes
|
||||
}
|
||||
$bmp.Dispose()
|
||||
}
|
||||
$headerSize = 6 + 16 * $entries.Count
|
||||
$offset = $headerSize
|
||||
foreach ($e in $entries) {
|
||||
$e | Add-Member -NotePropertyName Offset -NotePropertyValue $offset -Force
|
||||
$offset += $e.Size
|
||||
}
|
||||
$ms = New-Object System.IO.MemoryStream
|
||||
$bw = New-Object System.IO.BinaryWriter $ms
|
||||
$bw.Write([uint16]0) # Reserved
|
||||
$bw.Write([uint16]1) # Type: ICO
|
||||
$bw.Write([uint16]$entries.Count)
|
||||
foreach ($e in $entries) {
|
||||
$bw.Write([byte]($(if ($e.Width -ge 256) { 0 } else { $e.Width })))
|
||||
$bw.Write([byte]($(if ($e.Height -ge 256) { 0 } else { $e.Height })))
|
||||
$bw.Write([byte]0) # ColorCount
|
||||
$bw.Write([byte]0) # Reserved
|
||||
$bw.Write([uint16]1) # ColorPlanes
|
||||
$bw.Write([uint16]32) # BitsPerPixel
|
||||
$bw.Write([uint32]$e.Size)
|
||||
$bw.Write([uint32]$e.Offset)
|
||||
}
|
||||
foreach ($e in $entries) {
|
||||
$bw.Write($e.Bytes)
|
||||
}
|
||||
$bw.Flush()
|
||||
[System.IO.File]::WriteAllBytes($icoPath, $ms.ToArray())
|
||||
$bw.Dispose()
|
||||
$ms.Dispose()
|
||||
}
|
||||
|
||||
Write-Ico $pngPaths (Join-Path $resourcesDir "icon.ico")
|
||||
|
||||
# Keep a 256 PNG as 'icon.png' for in-app use, drop the smaller intermediates.
|
||||
Copy-Item (Join-Path $resourcesDir "icon-256.png") (Join-Path $resourcesDir "icon.png") -Force
|
||||
foreach ($s in $sizes) {
|
||||
Remove-Item (Join-Path $resourcesDir ("icon-$s.png")) -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
Write-Host "Generated icons in $resourcesDir"
|
||||
Get-ChildItem $resourcesDir | Format-Table Name, Length
|
||||
Reference in New Issue
Block a user