<# Эталонный кадр с РУССКИМ интерфейсом. Нужен как негативный тест: английская модель OCR читает кириллицу как бессмыслицу, и эту бессмыслицу нельзя ни переводить, ни закрывать плашками. На таком кадре правильный результат — ноль переведённых блоков. #> param([string]$Out = "$PSScriptRoot\..\dist\sample-ru.png") Add-Type -AssemblyName System.Drawing $W, $H = 1600, 900 $bmp = New-Object Drawing.Bitmap($W, $H, [Drawing.Imaging.PixelFormat]::Format32bppArgb) $g = [Drawing.Graphics]::FromImage($bmp) $g.SmoothingMode = 'AntiAlias' $g.TextRenderingHint = 'ClearTypeGridFit' function Brush($r, $gg, $b) { New-Object Drawing.SolidBrush ([Drawing.Color]::FromArgb($r, $gg, $b)) } function Fnt($size, $style = 'Regular') { New-Object Drawing.Font('Segoe UI', $size, [Drawing.FontStyle]::$style, [Drawing.GraphicsUnit]::Pixel) } function Text($s, $font, $brush, $x, $y) { $g.DrawString($s, $font, $brush, [single]$x, [single]$y) } $g.FillRectangle((Brush 32 34 42), 0, 0, $W, $H) $g.FillRectangle((Brush 24 26 32), 0, 0, 260, $H) $white = Brush 236 238 243 $grey = Brush 150 155 168 $body = Brush 205 210 220 # боковая панель — короткие подписи, на них и сыпался фильтр Text 'Быстрый доступ' (Fnt 12) $grey 20 18 Text 'Рабочий стол' (Fnt 14) $white 20 46 Text 'Загрузки' (Fnt 14) $white 20 76 Text 'Документы' (Fnt 14) $white 20 106 Text 'Изображения' (Fnt 14) $white 20 136 Text 'Этот компьютер' (Fnt 14) $white 20 176 Text 'Проекты' (Fnt 14) $white 20 206 Text 'Стрелец' (Fnt 14) $white 20 236 # панель инструментов Text 'Создать' (Fnt 13) $white 290 20 Text 'Вырезать' (Fnt 13) $white 370 20 Text 'Копировать' (Fnt 13) $white 460 20 Text 'Переименовать' (Fnt 13) $white 570 20 Text 'Сортировать' (Fnt 13) $white 700 20 Text 'Просмотреть' (Fnt 13) $white 810 20 # заголовки таблицы Text 'Имя' (Fnt 13) $grey 290 70 Text 'Дата изменения' (Fnt 13) $grey 600 70 Text 'Тип' (Fnt 13) $grey 820 70 Text 'Размер' (Fnt 13) $grey 980 70 # строки таблицы: имена файлов латиницей рядом с русскими типами $rows = @( @('config.json', '27.07.2026 13:05', 'Файл "JSON"', '3 КБ'), @('cache.json', '27.07.2026 13:17', 'Файл "JSON"', '18 КБ'), @('sample.png', '27.07.2026 13:05', 'Файл "PNG"', '41 КБ'), @('ScreenTranslator.exe', '27.07.2026 13:17', 'Приложение', '81 КБ') ) $y = 104 foreach ($r in $rows) { Text $r[0] (Fnt 14) $body 290 $y Text $r[1] (Fnt 13) $body 600 $y Text $r[2] (Fnt 13) $body 820 $y Text $r[3] (Fnt 13) $body 980 $y $y += 30 } # связный русский абзац $para = @( 'Выберите файлы, которые нужно переместить в архив. После подтверждения', 'операция будет выполнена в фоновом режиме, а исходные файлы останутся', 'на месте до завершения проверки контрольных сумм.' ) $y = 300 foreach ($line in $para) { Text $line (Fnt 15) $body 290 $y; $y += 26 } Text 'Элементов: 6' (Fnt 12) $grey 290 420 Text 'Выбран 1 элемент: 73,5 КБ' (Fnt 12) $grey 420 420 $g.Dispose() New-Item -ItemType Directory -Force -Path (Split-Path $Out -Parent) | Out-Null $bmp.Save($Out, [Drawing.Imaging.ImageFormat]::Png) $bmp.Dispose() Write-Host "Русский эталонный кадр: $Out"