# 一次性资产生成脚本:把 docs/screenshots 与 icons/dist 的原图缩放并转码到 site/assets。 # 站点本身零构建,这个脚本只在替换截图时手动重跑。 param( [string]$Repo = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path ) Add-Type -AssemblyName System.Drawing $outDir = $PSScriptRoot $srcShots = Join-Path $Repo 'docs\screenshots' $srcIcons = Join-Path $Repo 'icons\dist' function Save-Jpeg { param([System.Drawing.Bitmap]$Bitmap, [string]$Path, [int]$Quality = 88) $codec = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() | Where-Object { $_.MimeType -eq 'image/jpeg' } $params = New-Object System.Drawing.Imaging.EncoderParameters 1 $params.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter ([System.Drawing.Imaging.Encoder]::Quality), ([int]$Quality) $Bitmap.Save($Path, $codec, $params) $params.Dispose() } function Resize-Shot { param([string]$In, [string]$Out, [int]$MaxWidth = 1600, [int]$Quality = 88) $src = [System.Drawing.Image]::FromFile($In) try { $scale = [Math]::Min(1.0, $MaxWidth / $src.Width) $w = [int][Math]::Round($src.Width * $scale) $h = [int][Math]::Round($src.Height * $scale) $bmp = New-Object System.Drawing.Bitmap $w, $h try { $g = [System.Drawing.Graphics]::FromImage($bmp) $g.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic $g.PixelOffsetMode = [System.Drawing.Drawing2D.PixelOffsetMode]::HighQuality $g.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::HighQuality $g.DrawImage($src, 0, 0, $w, $h) $g.Dispose() Save-Jpeg -Bitmap $bmp -Path $Out -Quality $Quality "{0}`t{1}x{2}`t{3} KB" -f (Split-Path $Out -Leaf), $w, $h, [Math]::Round((Get-Item $Out).Length / 1KB) } finally { $bmp.Dispose() } } finally { $src.Dispose() } } $map = @( @{ In = 'PeopleLib_bAecy2Izab.png'; Out = 'shot-library.jpg' } @{ In = 'PeopleLib_34BtvLsqDE.png'; Out = 'shot-search.jpg' } @{ In = 'PeopleLib_ScQMUA2D24.png'; Out = 'shot-reader.jpg' } @{ In = 'PeopleLib_2N6zVpCFBA.png'; Out = 'shot-ai.jpg' } @{ In = 'ai-send-confirmation.png'; Out = 'shot-ai-confirm.jpg' } @{ In = 'pdf-annotations.png'; Out = 'shot-annotations.jpg' } ) foreach ($m in $map) { $in = Join-Path $srcShots $m.In if (Test-Path $in) { Resize-Shot -In $in -Out (Join-Path $outDir $m.Out) } else { Write-Warning "缺少源图 $in" } } foreach ($v in @('light', 'dark')) { foreach ($size in @(32, 256, 512)) { $in = Join-Path $srcIcons "$v\icon-$size.png" if (Test-Path $in) { Copy-Item $in (Join-Path $outDir "icon-$v-$size.png") -Force } } } # Open Graph 封面:深色底 + 应用图标 + 书库截图,1200x630。 $og = New-Object System.Drawing.Bitmap 1200, 630 try { $g = [System.Drawing.Graphics]::FromImage($og) $g.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic $g.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::HighQuality $g.TextRenderingHint = [System.Drawing.Text.TextRenderingHint]::ClearTypeGridFit $g.Clear([System.Drawing.ColorTranslator]::FromHtml('#12141a')) $shot = Join-Path $outDir 'shot-library.jpg' if (Test-Path $shot) { $img = [System.Drawing.Image]::FromFile($shot) try { $targetW = 660 $scale = $targetW / $img.Width $h = [int][Math]::Round($img.Height * $scale) $g.DrawImage($img, 500, [int]((630 - $h) / 2), $targetW, $h) } finally { $img.Dispose() } } $iconPath = Join-Path $outDir 'icon-dark-256.png' if (Test-Path $iconPath) { $icon = [System.Drawing.Image]::FromFile($iconPath) try { $g.DrawImage($icon, 72, 132, 112, 112) } finally { $icon.Dispose() } } $white = New-Object System.Drawing.SolidBrush ([System.Drawing.ColorTranslator]::FromHtml('#f4f5f7')) $muted = New-Object System.Drawing.SolidBrush ([System.Drawing.ColorTranslator]::FromHtml('#a8aeba')) $fTitle = New-Object System.Drawing.Font 'Microsoft YaHei', 44, ([System.Drawing.FontStyle]::Bold) $fSub = New-Object System.Drawing.Font 'Microsoft YaHei', 19 $fFoot = New-Object System.Drawing.Font 'Microsoft YaHei', 15 $g.DrawString('PeopleLib', $fTitle, $white, 68, 268) $g.DrawString("多源文献检索`n本地书库与内置阅读器", $fSub, $muted, 72, 348) $g.DrawString('reader.mesalogo.com', $fFoot, $muted, 72, 470) $g.Dispose() Save-Jpeg -Bitmap $og -Path (Join-Path $outDir 'og-cover.jpg') -Quality 86 "og-cover.jpg`t1200x630`t{0} KB" -f [Math]::Round((Get-Item (Join-Path $outDir 'og-cover.jpg')).Length / 1KB) } finally { $og.Dispose() }