# Переводчик экрана Наводит перевод поверх английского текста прямо на экране — как Яндекс.Переводчик по фото, только для монитора. Нажал горячую клавишу → английские надписи закрылись плашками под цвет фона, на них русский текст. Остальная картинка остаётся на месте. Работает с любой программой: игры, PDF, видео, интерфейсы, картинки — всё, что видно на экране. * Распознавание — встроенный в Windows OCR: офлайн, бесплатно, ничего ставить не надо. * Перевод — несколько движков с автоматическим переключением, если какой-то не отвечает. * Один файл `ScreenTranslator.exe` (81 КБ), без установщика и без .NET SDK. ## Как пользоваться | Клавиши | Действие | |---|---| | `Ctrl+Alt+Z` | перевести монитор, на котором сейчас курсор | | `Ctrl+Alt+X` | выделить область рамкой и перевести её | | `Esc` или повторное нажатие | закрыть перевод | | Пробел (удерживать) | подсмотреть оригинал под плашками | | Наведение мышью | показать оригинал одного фрагмента | | Клик по плашке | скопировать её перевод | | `Ctrl+C` | скопировать весь перевод | Значок в трее — те же команды плюс «Проверить переводчики» и правка настроек. Пока идёт распознавание и перевод, экран уже заморожен, а фрагменты подсвечены — видно, что программа работает. Полный цикл на мониторе 3440×1440 — около трёх секунд (0,6 с распознавание + ~2 с перевод), повтор того же текста — мгновенно из кэша. ## Установка Скопировать папку `dist` куда угодно и запустить `ScreenTranslator.exe`. Всё. Если Windows покажет «SmartScreen защитил ваш компьютер» — «Подробнее» → «Выполнить в любом случае» (файл без цифровой подписи). Автозапуск: `Win+R` → `shell:startup` → положить туда ярлык на exe. ### Требование одно: модель распознавания Нужен установленный в Windows языковой компонент «Распознавание текста» для английского. Проверить: значок в трее → «Проверить переводчики» покажет ошибку, если моделей нет. Ставится так: **Параметры → Время и язык → Язык и регион** → у английского языка `···` → **Компоненты языка** → отметить **Распознавание текста**. На большинстве систем уже стоит. ## Настройка Рядом с exe лежит `config.json` (создаётся при первом запуске). После правки — «Перечитать настройки» в трее, перезапуск не нужен. Самое полезное: ```jsonc "hotkeyTranslate": "Ctrl+Alt+Z", // своя комбинация, если эта занята "ocrLanguage": "en-US", // язык оригинала на экране "targetLang": "ru", // на какой переводить "overlayMode": "frozen", // frozen — стоп-кадр; live — плашки поверх живого экрана "captureScope": "monitor", // monitor — экран под курсором; all — все мониторы сразу "ocrScale": 2.0, // 1.0 быстрее, 2.0 точнее на мелком шрифте "detectForeign": true, // не трогать надписи на языке системы (см. ниже) "markTranslated": true, // подчёркивать переведённые места "chain": ["google", "lingva", "mymemory"] ``` ### Смешанный экран Английская модель OCR, встретив русскую надпись, читает её как бессмыслицу вроде `C03AaTb` или `Pa3Mep` — и без защиты программа переводила бы эту кашу, залепляя плашками весь русский интерфейс. Защита двухступенчатая: 1. `skipGarbage` — отсев по форме слов: цифра посреди слова, заглавная после строчной, символы-артефакты, имена файлов. 2. `detectForeign` — кадр дополнительно распознаётся моделью второго языка. Если она видит на этом месте кириллицу, надпись изначально русская и её не трогают. Это ещё примерно столько же времени на распознавание; выключается, если весь экран и так на одном языке. 3. Список ходовых английских слов ([EnglishWords.cs](src/EnglishWords.cs)) — арбитр в спорных случаях. Русская модель читает латинское «Cancel» как «Сапсеl», то есть по алфавиту оно неотличимо от русского «Профиль» → `npocbwlb`. Если основная модель выдала узнаваемое английское слово, верим ей. На эталонах это даёт 22 распознанных блока из 22 на английском кадре (ни одной потери) и 2 оставшихся из 20 на русском. Совсем идеально не будет: очень мелкие надписи (вкладки браузера, 8 px) обе модели читают плохо, и часть их может проскочить. **Если на экране мешанина языков — надёжнее `Ctrl+Alt+X` и рамка вокруг нужного куска.** ### Чего программа не умеет и не сможет Рабочий стол, панель задач, списки установленных программ — не её сценарий. Подписи там это названия приложений, а отличить название от обычного слова невозможно: «Steam», «Discord», «Wand» одновременно и то, и другое. Перевод получится буквальным и бессмысленным. Помогает `"minWords": 2` — тогда переводятся только фразы от двух слов, а одиночные подписи остаются как есть. Но за это приходится платить: на интерфейсе игры теряется половина надписей («Mining», «Search», «Consumable» — тоже одиночные слова), поэтому по умолчанию стоит `1`. ### Про переводчики и Россию `chain` — это порядок попыток. Первый ответивший движок используется, упавший временно исключается и пробуется следующий. Ничего перенастраивать при переезде в другую сеть не нужно — если Google недоступен, программа сама уйдёт на запасной. Что стоит знать: * **google** — бесплатный публичный эндпоинт, без ключа, лучшее соотношение качества и скорости. `translate.googleapis.com` в России не заблокирован (замедляли YouTube, а не API), но у отдельных провайдеров ТСПУ рвёт к нему TLS. Отсюда и нужна цепочка. * **lingva** — открытый шлюз к тому же Google на других адресах. Ровно тот случай, когда напрямую не пускает, а через шлюз проходит. Медленнее (2–4 с). * **mymemory** — последний рубеж, без ключа, лимит около 5000 слов в сутки на IP. * **yandex** — самый устойчивый канал внутри РФ, но нужен платный Yandex Cloud (`folderId` + API-ключ). * **deepl** — лучшее качество en→ru, есть бесплатный тариф с ключом. * **llm** — перевод целым экраном через Claude API: лучше держит контекст интерфейса, но платный по токенам и медленнее. * **libretranslate** / **relay** — свой сервер, ничего не уходит наружу. Проверить, что доступно из конкретной сети: трей → **Проверить переводчики** — покажет время ответа или ошибку по каждому. Через прокси (например, свой sing-box в режиме mixed): ```jsonc "proxy": "http://192.168.5.42:2080" ``` ### Свой релей Если публичные сервисы недоступны, а свой сервер есть — поднимите эндпоинт, принимающий `POST {"texts": [...], "from": "en", "to": "ru"}` и возвращающий `{"texts": [...]}` той же длины, затем: ```jsonc "chain": ["relay", "google"], "engines": { "relay": { "url": "https://ваш-домен/translate" } } ``` Внутри релей может ходить хоть в Google, хоть в локальную модель — клиенту всё равно. ## Приватность Распознавание идёт локально, наружу уходит **только распознанный текст** — картинка экрана никогда не покидает компьютер. Но текст с экрана всё же уходит в выбранный сервис перевода, поэтому для чувствительного содержимого используйте `libretranslate` или `relay` на своём сервере. Кэш переводов лежит рядом в `cache.json` — его можно удалять в любой момент. ## Сборка из исходников .NET SDK не нужен — используется Roslyn из Visual Studio Build Tools и сборки .NET Framework 4.8, которые уже есть в Windows. ```powershell .\build.ps1 # собрать в .\dist .\build.ps1 -Run # собрать и запустить .\build.ps1 -Test # плюс RenderTest.exe ``` `RenderTest.exe` — не сама программа, а диагностика: прогоняет весь конвейер без окна и сохраняет две картинки (как OCR разметил блоки и как лёг перевод). Запускать лучше из терминала; при двойном клике он всё равно отработает и подождёт Enter, а картинки положит в `%TEMP%\screen-translator-test`. ```powershell .\dist\RenderTest.exe --in кадр.png --out .\dist\test .\dist\RenderTest.exe --scale 1.0 --no-translate ``` Два эталонных кадра для прогонов рисуются скриптами: * `tools\make-sample.ps1` — англоязычный интерфейс. Проверка «всё ли переводится»: правильный результат — 22 блока. * `tools\make-sample-ru.ps1` — русский интерфейс. Негативная проверка: английская модель OCR читает кириллицу как кашу, и её нельзя ни переводить, ни закрывать плашками. Правильный результат — около 5 блоков (мелкие обрывки вроде «Tn»), было 20 до фильтра. Оба стоит прогонять после правок в `Blocks.cs`: ужесточение фильтра легко начинает резать короткие английские кнопки, и английский кадр это сразу показывает. Флаг `--expect файл.txt` считает, сколько заранее известных строк реально распозналось — без такой метрики улучшение и ухудшение на глаз выглядят одинаково убедительно. `--selftest` проверяет биграммную модель на примерах настоящих надписей и каши. ```powershell .\dist\RenderTest.exe --in wow.jpg --expect tools\expect-wow.txt --no-translate .\dist\RenderTest.exe --selftest ``` Текущие показатели (после каждой правки должны держаться): | Кадр | Метрика | Значение | |---|---|---| | Скриншот игры | распознано известных надписей | 14 из 14 | | Английский эталон | ложно отброшено | 0 | | Русский эталон | осталось непойманной каши | 2 из 20 | ## Что внутри | Файл | Зачем | |---|---| | `src/Program.cs` | трей, горячие клавиши, порядок работы | | `src/ScreenCapture.cs` | снимок экрана и отдельная копия пикселей для фоновой обработки | | `src/Ocr.cs` | Windows.Media.Ocr, увеличение кадра ради мелкого шрифта | | `src/Blocks.cs` | склейка строк в абзацы, отсев каши, подбор цветов плашки | | `src/Translators.cs` | движки перевода, цепочка фоллбеков, кэш | | `src/PlateRenderer.cs` | подбор кегля и отрисовка плашки | | `src/OverlayForm.cs` | окно поверх экрана | | `src/RegionSelector.cs` | выделение области рамкой | | `src/EnglishBigrams.cs` | частоты буквенных пар: отличает слово от каши распознавания | | `src/EnglishWords.cs` | список ходовых английских слов — арбитр в спорных случаях | Откуда взялись решения (короткий разбор чужого опыта): * Классические алгоритмы сегментации — RLSA, Docstrum, XY-cut, Voronoi — принимают решение «склеивать или нет» по одному сигналу, межстрочному зазору. В плотном интерфейсе он одинаков у строк абзаца и у соседних контролов, поэтому ни один из них эту задачу не решает. Работает только ансамбль независимых признаков — как в Tesseract (`paragraphs.h`, геометрия плюс пунктуация) и UIED, где графику детектируют отдельно от текста. * Отсюда четыре признака разрыва: разный фон, граница между строками, «строка не дотянула до правого края» (в абзаце короткой бывает только последняя) и несовпадение кегля. * Определение чужого языка — это не задача language identification: готовые детекторы (cld3, fastText) всегда выбирают какой-то язык из списка и уверенно зовут кашу английским. Нужна одноклассовая модель «похоже на настоящий английский», отсюда биграммы. * Проверено и отвергнуто: перевод в оттенки серого и инверсия тёмного фона перед OCR. Обещали заметный прирост, на замере не дали ничего (14 из 20 во всех вариантах), поэтому по умолчанию выключены, хотя в конфиге остались. Тонкие места, если будете править: * Приложение помечено `PerMonitorV2` — все координаты физические, иначе разметка OCR разъезжается с экраном при масштабе интерфейса больше 100 %. * OCR обводит только тело букв, без выносных элементов, поэтому плашка расширяется по вертикали — иначе сверху и снизу торчат хвосты оригинала. * Строки склеиваются в абзац по межстрочному интервалу и одинаковому кеглю: рваные строки переводятся заметно хуже целого абзаца.