Инструменты пользователя

Инструменты сайта


windows:scripts:powershell:wallpaper_text

Это старая версия документа!


Обои рабочего стола с текстом (wallpaper_text)

Описание

Создает обои рабочего стола с надписью из файла «wallpaper.txt» с содержимым в названии итоговых файлов.
При отсутствии файла он создается автоматичеки с содержимым «terminal-new».
Если файл «wallpaper.txt» существует но пустой, то создаются файлы картинки без надписей с однотонным полем.

Примеры

Код

wallpaper_text.ps1
# ============================================================
# File: wallpaper_text.ps1
# Fully universal version (PS5 + PS7 + .NET 9 safe)
# ============================================================
 
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$ErrorActionPreference = "Stop"
 
Write-Host "⚙️ Starting wallpaper generator..." -ForegroundColor Cyan
 
# ------------------------------------------------------------
# LOAD SYSTEM.DRAWING
# ------------------------------------------------------------
try {
    Add-Type -AssemblyName System.Drawing -ErrorAction Stop
}
catch {
    Add-Type -AssemblyName System.Drawing.Common
}
 
# ------------------------------------------------------------
# PARAMETERS
# ------------------------------------------------------------
$MARGIN_RATIO   = 0.90
$BASE_FONT_SIZE = 150
$ANGLE          = -7
$TEXT_FILE      = "wallpaper.txt"
$FONT_PATH      = "C:\Windows\Fonts\segoeui.ttf"
$LINE_SPACING   = 1.0
 
$BgColorRaw   = "10,70,90"
$TextColorRaw = "100,150,165"
 
function Convert-RGB([string]$rgb) {
    $p = $rgb.Split(",")
    [System.Drawing.Color]::FromArgb(255, [int]$p[0], [int]$p[1], [int]$p[2])
}
 
$BG_COLOR   = Convert-RGB $BgColorRaw
$TEXT_COLOR = Convert-RGB $TextColorRaw
 
# ------------------------------------------------------------
# CREATE DEFAULT TEXT FILE IF MISSING
# ------------------------------------------------------------
if (-not (Test-Path -LiteralPath $TEXT_FILE)) {
    "terminal-new" | Set-Content -LiteralPath $TEXT_FILE -Encoding UTF8
}
 
# ------------------------------------------------------------
# READ + NORMALIZE
# ------------------------------------------------------------
function Read-NormalizedUtf8([string]$path) {
    $bytes = [System.IO.File]::ReadAllBytes($path)
    $txt = [System.Text.Encoding]::UTF8.GetString($bytes)
    $txt = $txt.Replace("`r`n","`n").Replace("`r","`n")
    [System.IO.File]::WriteAllText($path, $txt, [System.Text.UTF8Encoding]::new($false))
    return $txt
}
 
$textContent = Read-NormalizedUtf8 $TEXT_FILE
 
$lines = $textContent.Split("`n") |
    ForEach-Object { $_.Trim() } |
    Where-Object { $_ -ne "" }
 
$TEXT_MODE = $true
if (-not $lines) {
    Write-Host "ℹ️ No text found — background only mode." -ForegroundColor Yellow
    $TEXT_MODE = $false
}
 
# ------------------------------------------------------------
# SAFE OUTPUT NAME
# ------------------------------------------------------------
$joined = $lines -join " "
$safe = ($joined -replace '[<>:"/\\|?*]', '').Trim()
if ($safe.Length -gt 80) { $safe = $safe.Substring(0,80) }
if (-not $safe) { $safe = "background" }
 
# ------------------------------------------------------------
# FAST BOUNDING BOX (LOCKBITS VERSION)
# ------------------------------------------------------------
function Get-BoundingBoxAlpha($bmp) {
 
    $rect = New-Object System.Drawing.Rectangle(0,0,$bmp.Width,$bmp.Height)
    $data = $bmp.LockBits(
        $rect,
        [System.Drawing.Imaging.ImageLockMode]::ReadOnly,
        [System.Drawing.Imaging.PixelFormat]::Format32bppArgb
    )
 
    $minX = [int]::MaxValue
    $minY = [int]::MaxValue
    $maxX = -1
    $maxY = -1
    $hasContent = $false
 
    try {
        $bytes = New-Object byte[] ($data.Stride * $bmp.Height)
        [System.Runtime.InteropServices.Marshal]::Copy(
            $data.Scan0,
            $bytes,
            0,
            $bytes.Length
        )
 
        for ($y = 0; $y -lt $bmp.Height; $y++) {
            for ($x = 0; $x -lt $bmp.Width; $x++) {
 
                $index = $y * $data.Stride + $x * 4
                $alpha = $bytes[$index + 3]
 
                if ($alpha -ne 0) {
                    if ($x -lt $minX) { $minX = $x }
                    if ($x -gt $maxX) { $maxX = $x }
                    if ($y -lt $minY) { $minY = $y }
                    if ($y -gt $maxY) { $maxY = $y }
                    $hasContent = $true
                }
            }
        }
    }
    finally {
        $bmp.UnlockBits($data)
    }
 
    return [PSCustomObject]@{
        MinX = $minX
        MinY = $minY
        MaxX = $maxX
        MaxY = $maxY
        HasContent = $hasContent
    }
}
 
# ------------------------------------------------------------
# ORIENTATIONS
# ------------------------------------------------------------
$orientations = @(
    @{ Name = "landscape"; Width = 1920; Height = 1080 },
    @{ Name = "portrait";  Width = 1080; Height = 1920 }
)
 
# ------------------------------------------------------------
# MAIN LOOP
# ------------------------------------------------------------
foreach ($o in $orientations) {
 
    Write-Host ""
    Write-Host "===============================" -ForegroundColor Yellow
    Write-Host " Generating $($o.Name)..."
    Write-Host "==============================="
 
    $WIDTH  = $o.Width
    $HEIGHT = $o.Height
 
    if (-not $TEXT_MODE) {
 
        $bitmap = New-Object System.Drawing.Bitmap(
            $WIDTH,$HEIGHT,[System.Drawing.Imaging.PixelFormat]::Format24bppRgb
        )
        $gfx = [System.Drawing.Graphics]::FromImage($bitmap)
        $gfx.Clear($BG_COLOR)
 
        $OUTPUT_FILE = "${safe}_$($o.Name).png"
        $bitmap.Save($OUTPUT_FILE,[System.Drawing.Imaging.ImageFormat]::Png)
 
        Write-Host "✔ Generated (background only): $OUTPUT_FILE" -ForegroundColor Green
 
        $gfx.Dispose()
        $bitmap.Dispose()
        continue
    }
 
    $SAFE_WIDTH = if ($o.Name -eq "landscape") { 1440 } else { $WIDTH }
    Write-Host "SAFE_WIDTH = $SAFE_WIDTH"
 
    function New-ItalicFont($size) {
        New-Object System.Drawing.Font($FONT_PATH,$size,[System.Drawing.FontStyle]::Italic)
    }
 
    # PASS 1
    $fontSize = $BASE_FONT_SIZE
    $tmpBmp = New-Object System.Drawing.Bitmap(100,100)
    $tmpGfx = [System.Drawing.Graphics]::FromImage($tmpBmp)
 
    while ($fontSize -ge 20) {
        $f = New-ItalicFont $fontSize
        $maxW = ($lines | ForEach-Object { $tmpGfx.MeasureString($_,$f).Width } |
            Measure-Object -Maximum).Maximum
        if ($maxW -le ($SAFE_WIDTH * $MARGIN_RATIO)) { $f.Dispose(); break }
        $f.Dispose()
        $fontSize -= 5
    }
 
    $tmpGfx.Dispose()
    $tmpBmp.Dispose()
 
    Write-Host "Pre-rotation font guess: $fontSize px"
 
    # PASS 2
    while ($true) {
 
        $font = New-ItalicFont $fontSize
 
        $textLayer = New-Object System.Drawing.Bitmap(
            $WIDTH,$HEIGHT,[System.Drawing.Imaging.PixelFormat]::Format32bppArgb
        )
        $tg = [System.Drawing.Graphics]::FromImage($textLayer)
        $tg.SmoothingMode = "AntiAlias"
        $tg.TextRenderingHint = "ClearTypeGridFit"
        $tg.Clear([System.Drawing.Color]::Transparent)
 
        $lineHeight  = [int]($tg.MeasureString("A",$font).Height)
        $totalHeight = [int]($lineHeight * $lines.Count * $LINE_SPACING)
        $y = ($HEIGHT - $totalHeight)/2
 
        $brush = New-Object System.Drawing.SolidBrush($TEXT_COLOR)
 
        foreach ($line in $lines) {
            $sz = $tg.MeasureString($line,$font)
            $x = ($WIDTH - $sz.Width)/2
            $tg.DrawString($line,$font,$brush,$x,$y)
            $y += [int]($lineHeight * $LINE_SPACING)
        }
 
        $rotated = New-Object System.Drawing.Bitmap(
            $WIDTH,$HEIGHT,[System.Drawing.Imaging.PixelFormat]::Format32bppArgb
        )
        $rg = [System.Drawing.Graphics]::FromImage($rotated)
 
        $mx = New-Object System.Drawing.Drawing2D.Matrix
        $mx.RotateAt($ANGLE,[System.Drawing.PointF]::new($WIDTH/2,$HEIGHT/2))
        $rg.Transform = $mx
        $rg.DrawImage($textLayer,0,0)
        $rg.ResetTransform()
 
        $box = Get-BoundingBoxAlpha $rotated
 
        if ($box.HasContent) {
            $rotW = $box.MaxX - $box.MinX
            $rotH = $box.MaxY - $box.MinY
 
            if (
                $rotW -le ($WIDTH  * $MARGIN_RATIO) -and
                $rotH -le ($HEIGHT * $MARGIN_RATIO)
            ) {
                Write-Host "Final font size: $fontSize px"
                break
            }
        }
 
        $brush.Dispose()
        $font.Dispose()
        $tg.Dispose()
        $textLayer.Dispose()
        $rg.Dispose()
        $rotated.Dispose()
 
        $fontSize -= 5
        if ($fontSize -lt 20) {
            Write-Host "❌ Cannot scale text to fit!" -ForegroundColor Red
            break
        }
    }
 
    # FINAL DRAW
    $bitmap = New-Object System.Drawing.Bitmap(
        $WIDTH,$HEIGHT,[System.Drawing.Imaging.PixelFormat]::Format24bppRgb
    )
    $gfx = [System.Drawing.Graphics]::FromImage($bitmap)
    $gfx.Clear($BG_COLOR)
 
    $offX = ($WIDTH  - ($box.MaxX - $box.MinX)) / 2 - $box.MinX
    $offY = ($HEIGHT - ($box.MaxY - $box.MinY)) / 2 - $box.MinY
 
    $gfx.DrawImage($rotated,$offX,$offY)
 
    $OUTPUT_FILE = "${safe}_$($o.Name).png"
    $bitmap.Save($OUTPUT_FILE,[System.Drawing.Imaging.ImageFormat]::Png)
 
    Write-Host "✔ Generated: $OUTPUT_FILE" -ForegroundColor Green
 
    $brush.Dispose()
    $font.Dispose()
    $gfx.Dispose()
    $bitmap.Dispose()
    $tg.Dispose()
    $textLayer.Dispose()
    $rg.Dispose()
    $rotated.Dispose()
}
 
Write-Host "🎉 All wallpapers generated!"
windows/scripts/powershell/wallpaper_text.1772091137.txt.gz · Последнее изменение:

Если не указано иное, содержимое этой вики предоставляется на условиях следующей лицензии: CC Attribution 4.0 International
CC Attribution 4.0 International Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki