Skip to content

feat(ocr): let a preset read several languages - #1229

Open
KnifeLemon wants to merge 4 commits into
mainfrom
feat/ocr-several-languages
Open

KnifeLemon wants to merge 4 commits into
mainfrom
feat/ocr-several-languages

Conversation

@KnifeLemon

@KnifeLemon KnifeLemon commented Nov 6, 2026 •

Copy link
Copy Markdown
Owner

What does this change?

Fixes #1123. A preset's OCR can now read more than one language, for scans that mix them (Simplified Chinese + English, for example).

  • Settings: PdfOptions.OcrLanguage stays one string: one code, or several joined with +, the main language first (chi_sim+eng), which is what Tesseract's -l takes. Older settings with one code read as before, so there is no schema migration. An older Filee reading a joined value doesn't find it in its list and reads English, without an error.
  • One reader: OcrLanguages.Parse is what every reader now goes through. Codes not in the list are left out (only listed codes ever reach a path or Tesseract's command line), repeats count once, and with none left English is read, as an unknown code did before.
  • Tesseract: each language's data goes through the existing OcrLanguages.EnsureAsync download and is copied into the job's tessdata. A failed download refuses the file with error.ocr_language_download, naming that language, the way a single language does today.
  • Apple Vision: the other reader of the setting. The languages are asked for in their order. English is added when it wasn't chosen and goes last unless it is the main language. If Vision doesn't read one of them, all of them go to Tesseract, or the file is refused naming that language when Tesseract isn't installed. If Vision refuses a combination it retries with one language fewer, down to the main language alone (before: straight to the first).
  • Preset editor: the "Language of the text" list stays as it was for the main language. Below it, "Other languages in the text" has a list with an Add button and a row with a remove button per added language.
    • A language picked in the list but not added still counts when saving, and stays picked when a row is removed or the main language changes.
    • Making an added language the main one trades places with the old main language, so neither is lost. Choosing a language that wasn't added replaces the main language, as before.
    • Rows show the download size like the main list. On a Mac, a language Vision can't read among the chosen ones sends them all to Tesseract, so the languages Vision reads show their size too. For this the lists hold OcrLanguageChoice, whose detail can change while the window is open.
    • Four new strings, in all 20 language files (the Add button reuses group.add).
  • Docs: docs/ENGINES.md.

Type of change

  • Bug fix
  • New feature or improvement
  • New format or engine
  • Translation
  • Documentation
  • Build, CI or dependencies

How was it tested?

  • dotnet format --verify-no-changes on the changed C# files
  • Targeted dotnet test, on Windows 11 with Tesseract 5.4 (not the whole suites):
    • Filee.Engines.Tests: OcrLanguageListTests, OcrTests, VisionLanguageTests, VisionConverterTests, AppleVisionTests (44 tests: 39 passed, the 5 AppleVisionTests skipped off a Mac). New real runs: a scan in Russian + English is read only with rus+eng (with eng alone the Russian word is missing), and the scan of the issue, Simplified Chinese + English, reads both with chi_sim+eng; both download their language data. Others are new tests for parsing and bad codes, the failed download, and Vision's language order, mixed languages and fallback, with a stand-in recognizer.
    • Filee.App.Tests: LocalizationTests (key and placeholder parity) and the preset editor tests (222 tests, all passed). Preset_editor_reads_and_saves_several_text_recognition_languages covers loading, adding, removing, changing the main language, saving and older settings, rendered in English and Simplified Chinese. A_language_picked_but_not_added_stays_picked_while_the_lists_change runs with the window shown, so the real ComboBox is attached; it failed before the fix. Preset_editor_shows_the_download_of_a_language_vision_reads_when_tesseract_would_read_them_all uses a stand-in for what Vision reads.
  • Tried it in the app: not clicked through in the running app; the editor was checked in the headless render below.

Not tested here: real Apple Vision (no Mac here). The new AppleVisionTests.Text_in_two_languages_is_read_with_both reads Korean + English in both orders, and only runs in the macOS CI jobs. Translations other than English were written without a native review.

Screenshots (UI changes)

Preset editor with chi_sim+eng (English, light theme). English shows no size because its data is already downloaded here:

Preset editor: main language Simplified Chinese, English added under "Other languages in the text"

Checklist

  • New UI strings are in all src/Filee.App/Assets/i18n/*.json files
  • New third-party code or binaries are listed in THIRD-PARTY-NOTICES.md (none)
  • The PR does one thing (unrelated changes go in a separate PR)

🤖 Generated with Claude Code

Scans that mix languages (Simplified Chinese and English, say) read badly
with one language. PdfOptions.OcrLanguage now holds one code or several
joined with + as Tesseract takes them (chi_sim+eng), so older settings
keep working and no migration is needed. OcrLanguages.Parse is the one
reader: unlisted codes are left out, repeats count once, none left means
English.

Tesseract gets every language's data through the existing download, and a
failed download names its language. Apple Vision asks for the languages in
their order with English last; one it doesn't read sends them all to
Tesseract, or names that language when Tesseract is missing. The preset
editor keeps the main language list and adds "Other languages in the text".

Fixes #1123

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the feature New features label Nov 6, 2026
KnifeLemon and others added 3 commits November 7, 2026 02:55
From the review of #1229:

- The "add a language" list is refreshed in place, so a language picked
  but not added stays picked when a row is removed or the main language
  changes; clearing the list made the combo box drop it.
- An added language made the main one trades places with the old main
  language, which used to be lost.
- Apple Vision keeps English first when it is the main language, so a
  refused combination falls back to it, not to the other language.
- On a Mac, a language Vision can't read among the chosen ones sends them
  all to Tesseract, so the others show their download size too. For that
  the OCR lists hold OcrLanguageChoice, whose detail can change.
- AppleVisionTests read Korean and English in both orders on real Vision.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With "eng+kor" Vision read the English line and dropped the Korean one on
both Mac runners, while "kor+eng" read both. Those languages now go ahead
of the others whatever order was picked; the rest keep theirs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ocr能力

1 participant