188 lines
6.3 KiB
PowerShell
188 lines
6.3 KiB
PowerShell
[CmdletBinding()]
|
|
param(
|
|
[string] $Root = (Split-Path -Parent $PSScriptRoot)
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
Add-Type -AssemblyName System.Drawing
|
|
|
|
$sourcePath = Join-Path $Root 'assets\icons\app_icon.png'
|
|
if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) {
|
|
throw "App icon source was not found: $sourcePath"
|
|
}
|
|
|
|
function New-ResizedBitmap {
|
|
param(
|
|
[Drawing.Image] $Source,
|
|
[int] $Width,
|
|
[int] $Height,
|
|
[int] $Padding = 0,
|
|
[Drawing.Color] $Background = [Drawing.Color]::Transparent,
|
|
[switch] $SharpenSmallAlpha
|
|
)
|
|
|
|
$bitmap = [Drawing.Bitmap]::new($Width, $Height, [Drawing.Imaging.PixelFormat]::Format32bppArgb)
|
|
$graphics = [Drawing.Graphics]::FromImage($bitmap)
|
|
try {
|
|
$graphics.CompositingMode = [Drawing.Drawing2D.CompositingMode]::SourceCopy
|
|
$graphics.CompositingQuality = [Drawing.Drawing2D.CompositingQuality]::HighQuality
|
|
$graphics.InterpolationMode = [Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
|
|
$graphics.PixelOffsetMode = [Drawing.Drawing2D.PixelOffsetMode]::HighQuality
|
|
$graphics.SmoothingMode = [Drawing.Drawing2D.SmoothingMode]::HighQuality
|
|
$graphics.Clear($Background)
|
|
|
|
$availableWidth = $Width - (2 * $Padding)
|
|
$availableHeight = $Height - (2 * $Padding)
|
|
$scale = [Math]::Min($availableWidth / $Source.Width, $availableHeight / $Source.Height)
|
|
$drawWidth = [Math]::Max(1, [int][Math]::Round($Source.Width * $scale))
|
|
$drawHeight = [Math]::Max(1, [int][Math]::Round($Source.Height * $scale))
|
|
$drawX = [int][Math]::Floor(($Width - $drawWidth) / 2)
|
|
$drawY = [int][Math]::Floor(($Height - $drawHeight) / 2)
|
|
$attributes = [Drawing.Imaging.ImageAttributes]::new()
|
|
try {
|
|
$attributes.SetWrapMode([Drawing.Drawing2D.WrapMode]::TileFlipXY)
|
|
$graphics.DrawImage(
|
|
$Source,
|
|
[Drawing.Rectangle]::new($drawX, $drawY, $drawWidth, $drawHeight),
|
|
0,
|
|
0,
|
|
$Source.Width,
|
|
$Source.Height,
|
|
[Drawing.GraphicsUnit]::Pixel,
|
|
$attributes)
|
|
} finally {
|
|
$attributes.Dispose()
|
|
}
|
|
} finally {
|
|
$graphics.Dispose()
|
|
}
|
|
|
|
if ($SharpenSmallAlpha) {
|
|
for ($y = 0; $y -lt $Height; $y++) {
|
|
for ($x = 0; $x -lt $Width; $x++) {
|
|
$color = $bitmap.GetPixel($x, $y)
|
|
if ($color.A -le 10) {
|
|
$bitmap.SetPixel($x, $y, [Drawing.Color]::Transparent)
|
|
} else {
|
|
$alpha = if ($color.A -ge 244) { 255 } else { [Math]::Min(255, [int](($color.A - 10) * 255 / 234)) }
|
|
$bitmap.SetPixel($x, $y, [Drawing.Color]::FromArgb($alpha, 0, 114, 255))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $bitmap
|
|
}
|
|
|
|
function Get-PngBytes([Drawing.Bitmap] $Bitmap) {
|
|
$stream = [IO.MemoryStream]::new()
|
|
try {
|
|
$Bitmap.Save($stream, [Drawing.Imaging.ImageFormat]::Png)
|
|
return $stream.ToArray()
|
|
} finally {
|
|
$stream.Dispose()
|
|
}
|
|
}
|
|
|
|
function Write-PngIconFile([string] $Path, [hashtable] $Frames) {
|
|
$orderedSizes = @($Frames.Keys | ForEach-Object { [int] $_ } | Sort-Object)
|
|
$headerSize = 6 + (16 * $orderedSizes.Count)
|
|
$offset = $headerSize
|
|
$stream = [IO.MemoryStream]::new()
|
|
$writer = [IO.BinaryWriter]::new($stream)
|
|
try {
|
|
$writer.Write([uint16] 0)
|
|
$writer.Write([uint16] 1)
|
|
$writer.Write([uint16] $orderedSizes.Count)
|
|
foreach ($size in $orderedSizes) {
|
|
$bytes = [byte[]] $Frames[$size]
|
|
$writer.Write([byte] $(if ($size -eq 256) { 0 } else { $size }))
|
|
$writer.Write([byte] $(if ($size -eq 256) { 0 } else { $size }))
|
|
$writer.Write([byte] 0)
|
|
$writer.Write([byte] 0)
|
|
$writer.Write([uint16] 1)
|
|
$writer.Write([uint16] 32)
|
|
$writer.Write([uint32] $bytes.Length)
|
|
$writer.Write([uint32] $offset)
|
|
$offset += $bytes.Length
|
|
}
|
|
foreach ($size in $orderedSizes) {
|
|
$writer.Write([byte[]] $Frames[$size])
|
|
}
|
|
$writer.Flush()
|
|
$directory = Split-Path -Parent $Path
|
|
if ($directory) { [IO.Directory]::CreateDirectory($directory) | Out-Null }
|
|
[IO.File]::WriteAllBytes($Path, $stream.ToArray())
|
|
} finally {
|
|
$writer.Dispose()
|
|
$stream.Dispose()
|
|
}
|
|
}
|
|
|
|
function Save-Logo {
|
|
param(
|
|
[Drawing.Image] $Source,
|
|
[string] $Path,
|
|
[int] $Width,
|
|
[int] $Height,
|
|
[int] $Padding,
|
|
[Drawing.Color] $Background = [Drawing.Color]::Transparent
|
|
)
|
|
$bitmap = New-ResizedBitmap $Source $Width $Height $Padding $Background
|
|
try {
|
|
[IO.Directory]::CreateDirectory((Split-Path -Parent $Path)) | Out-Null
|
|
$bitmap.Save($Path, [Drawing.Imaging.ImageFormat]::Png)
|
|
} finally {
|
|
$bitmap.Dispose()
|
|
}
|
|
}
|
|
|
|
$loaded = [Drawing.Bitmap]::FromFile($sourcePath)
|
|
try {
|
|
$master = [Drawing.Bitmap]::new($loaded)
|
|
} finally {
|
|
$loaded.Dispose()
|
|
}
|
|
|
|
try {
|
|
$frames = @{}
|
|
foreach ($size in @(16, 20, 24, 32, 40, 48, 64, 96, 128, 256)) {
|
|
$frame = New-ResizedBitmap $master $size $size 0 ([Drawing.Color]::Transparent) -SharpenSmallAlpha:($size -le 24)
|
|
try {
|
|
$frames[$size] = Get-PngBytes $frame
|
|
} finally {
|
|
$frame.Dispose()
|
|
}
|
|
}
|
|
|
|
$iconTargets = @(
|
|
(Join-Path $Root 'assets\icon.ico'),
|
|
(Join-Path $Root 'assets\icons\app_icon.ico'),
|
|
(Join-Path $Root 'src\box-winUI\Assets\app_icon.ico'),
|
|
(Join-Path $Root 'src\YMhut.Box.PluginTauriHost\src-tauri\icons\icon.ico')
|
|
)
|
|
foreach ($target in $iconTargets) {
|
|
Write-PngIconFile $target $frames
|
|
}
|
|
|
|
$normalizedSource = Join-Path ([IO.Path]::GetTempPath()) ("ymhut-app-icon-{0}.png" -f [Guid]::NewGuid().ToString('N'))
|
|
try {
|
|
$master.Save($normalizedSource, [Drawing.Imaging.ImageFormat]::Png)
|
|
Copy-Item -LiteralPath $normalizedSource -Destination (Join-Path $Root 'assets\icons\app_icon.png') -Force
|
|
Copy-Item -LiteralPath $normalizedSource -Destination (Join-Path $Root 'assets\icons\icon.png') -Force
|
|
} finally {
|
|
Remove-Item -LiteralPath $normalizedSource -Force -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
$projectAssets = Join-Path $Root 'src\box-winUI\Assets'
|
|
Save-Logo $master (Join-Path $projectAssets 'StoreLogo.png') 50 50 5
|
|
Save-Logo $master (Join-Path $projectAssets 'Square44x44Logo.png') 44 44 4
|
|
Save-Logo $master (Join-Path $projectAssets 'Square150x150Logo.png') 150 150 16
|
|
Save-Logo $master (Join-Path $projectAssets 'LockScreenLogo.png') 70 70 8
|
|
Save-Logo $master (Join-Path $projectAssets 'Wide310x150Logo.png') 310 150 24 ([Drawing.Color]::FromArgb(255, 245, 246, 247))
|
|
} finally {
|
|
$master.Dispose()
|
|
}
|
|
|
|
Write-Host 'Generated DPI-aware YMhut Box application icons.'
|