HomeStream/Assets/build-icon.ps1

125 lines
4.5 KiB
PowerShell
Raw Normal View History

2026-05-10 23:25:29 +02:00
# SVG → multi-size .ico mittels WPF (Bordmittel, kein extra Tool nötig)
# Generiert logo.ico mit 16, 32, 48, 64, 128, 256 Pixeln
Add-Type -AssemblyName PresentationCore, PresentationFramework, WindowsBase
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$IcoPath = Join-Path $ScriptDir 'logo.ico'
function New-LogoBitmap {
param([int]$Size)
$dv = [System.Windows.Media.DrawingVisual]::new()
$dc = $dv.RenderOpen()
$scale = $Size / 256.0
# Hintergrund
$bgRect = [System.Windows.Rect]::new(8 * $scale, 8 * $scale, 240 * $scale, 240 * $scale)
$bgBrush = [System.Windows.Media.SolidColorBrush]::new(
[System.Windows.Media.Color]::FromRgb(0x1A, 0x1A, 0x1A))
$dc.DrawRoundedRectangle($bgBrush, $null, $bgRect, 40 * $scale, 40 * $scale)
# Blauer Gradient
$gradStart = [System.Windows.Media.Color]::FromRgb(0x00, 0x78, 0xD4)
$gradEnd = [System.Windows.Media.Color]::FromRgb(0x00, 0x5A, 0x9E)
$grad = [System.Windows.Media.LinearGradientBrush]::new($gradStart, $gradEnd, 90)
$grad.Freeze()
# Bildschirm-Rahmen
$screenRect = [System.Windows.Rect]::new(40 * $scale, 56 * $scale, 176 * $scale, 120 * $scale)
$screenPen = [System.Windows.Media.Pen]::new($grad, 6 * $scale)
$dc.DrawRoundedRectangle($null, $screenPen, $screenRect, 10 * $scale, 10 * $scale)
# Streaming-Wellen
$wavePen = [System.Windows.Media.Pen]::new($grad, 5 * $scale)
$wavePen.StartLineCap = 'Round'
$wavePen.EndLineCap = 'Round'
foreach ($wave in @(@(70, 140, 90, 110, 120, 110), @(70, 140, 100, 90, 145, 90), @(70, 140, 110, 70, 170, 70))) {
$geom = [System.Windows.Media.StreamGeometry]::new()
$ctx = $geom.Open()
$ctx.BeginFigure([System.Windows.Point]::new($wave[0] * $scale, $wave[1] * $scale), $false, $false)
$ctx.QuadraticBezierTo(
[System.Windows.Point]::new($wave[2] * $scale, $wave[3] * $scale),
[System.Windows.Point]::new($wave[4] * $scale, $wave[5] * $scale), $true, $false)
$ctx.Close()
$geom.Freeze()
$dc.DrawGeometry($null, $wavePen, $geom)
}
# Punkt am Ursprung
$dc.DrawEllipse($grad, $null,
[System.Windows.Point]::new(70 * $scale, 140 * $scale),
6 * $scale, 6 * $scale)
# Standfuß
$foot1 = [System.Windows.Rect]::new(100 * $scale, 184 * $scale, 56 * $scale, 8 * $scale)
$foot2 = [System.Windows.Rect]::new( 80 * $scale, 196 * $scale, 96 * $scale, 8 * $scale)
$dc.DrawRoundedRectangle($grad, $null, $foot1, 2 * $scale, 2 * $scale)
$dc.DrawRoundedRectangle($grad, $null, $foot2, 3 * $scale, 3 * $scale)
$dc.Close()
$rtb = [System.Windows.Media.Imaging.RenderTargetBitmap]::new(
$Size, $Size, 96, 96, [System.Windows.Media.PixelFormats]::Pbgra32)
$rtb.Render($dv)
return $rtb
}
function Get-PngBytes {
param($bitmap)
$encoder = [System.Windows.Media.Imaging.PngBitmapEncoder]::new()
$encoder.Frames.Add([System.Windows.Media.Imaging.BitmapFrame]::Create($bitmap))
$ms = [System.IO.MemoryStream]::new()
$encoder.Save($ms)
$bytes = $ms.ToArray()
$ms.Dispose()
return ,$bytes
}
# Generierung mit ArrayList damit Wrapping vorhersehbar ist
$sizes = @(16, 32, 48, 64, 128, 256)
$pngList = New-Object System.Collections.ArrayList
foreach ($size in $sizes) {
Write-Host " Rendere ${size}x${size}..."
$bmp = New-LogoBitmap -Size $size
$bytes = Get-PngBytes $bmp
[void]$pngList.Add($bytes)
Write-Host " PNG: $($bytes.Length) bytes"
}
# ICO bauen
$out = [System.IO.MemoryStream]::new()
$bw = [System.IO.BinaryWriter]::new($out)
$bw.Write([UInt16]0) # reserved
$bw.Write([UInt16]1) # type = ICO
$bw.Write([UInt16]$pngList.Count) # count
$dataOffset = 6 + ($pngList.Count * 16)
for ($i = 0; $i -lt $pngList.Count; $i++) {
$size = $sizes[$i]
$w = if ($size -eq 256) { 0 } else { $size }
$h = if ($size -eq 256) { 0 } else { $size }
$len = $pngList[$i].Length
$bw.Write([byte]$w)
$bw.Write([byte]$h)
$bw.Write([byte]0)
$bw.Write([byte]0)
$bw.Write([UInt16]1)
$bw.Write([UInt16]32)
$bw.Write([UInt32]$len)
$bw.Write([UInt32]$dataOffset)
$dataOffset += $len
}
for ($i = 0; $i -lt $pngList.Count; $i++) {
$bytes = $pngList[$i]
$bw.Write($bytes, 0, $bytes.Length)
}
$bw.Flush()
[System.IO.File]::WriteAllBytes($IcoPath, $out.ToArray())
$bw.Close()
$out.Dispose()
$icoSize = (Get-Item $IcoPath).Length
Write-Host "`nFertig: $IcoPath ($icoSize Bytes, $($pngList.Count) Größen)"