Skip to content

Initial implementation for OCRmyPDF#15712

Merged
subhramit merged 47 commits into
JabRef:mainfrom
ZiadAbdElFatah:feature-OCR
May 23, 2026
Merged

Initial implementation for OCRmyPDF#15712
subhramit merged 47 commits into
JabRef:mainfrom
ZiadAbdElFatah:feature-OCR

Conversation

@ZiadAbdElFatah

@ZiadAbdElFatah ZiadAbdElFatah commented May 11, 2026

Copy link
Copy Markdown
Collaborator

Related issues and pull requests

Initial implementation for #13267

PR Description

Initial implementation for OCR integration in JabRef, which uses OCRmyPDF as the only engine, and has a very simple implementation to just test the feature integration.

Steps to test

  1. Select any entry in any library and link jablib/src/test/resources/pdfs/scanned-image-only.pdf file to it
image 2. Right click it and choose "Perform OCR and embed text to a new PDF file" image 3. The new OCRed PDF is created in the same directory `jablib/src/test/resources/pdfs/scanned-image-only_ocr.pdf` image
  • Differences between the old and new PDF:
    Selecting text image
    Searching text
image

Checklist

  • I own the copyright of the code submitted and I license it under the MIT license
  • I manually tested my changes in running JabRef (always required)
  • [/] I added JUnit tests for changes (if applicable)
  • I added screenshots in the PR description (if change is visible to the user)
  • [/] I added a screenshot in the PR description showing a library with a single entry with me as author and as title the issue number
  • I described the change in CHANGELOG.md in a way that can be understood by the average user (if change is visible to the user)
  • I checked the user documentation for up to dateness and submitted a pull request to our user documentation repository

@calixtus

Copy link
Copy Markdown
Member

I like the data oriented approach very much.

Please use '///' markdown javadoc

@github-actions github-actions Bot added the status: changes-required Pull requests that are not yet complete label May 11, 2026
Comment thread jablib/src/main/java/org/jabref/logic/ocr/OcrEngine.java Outdated
Comment thread jablib/src/main/java/org/jabref/logic/ocr/OcrMyPdfEngine.java Outdated
Comment thread jablib/src/main/java/org/jabref/logic/ocr/OcrEngine.java Outdated
Comment thread jablib/src/main/java/org/jabref/logic/ocr/OcrMyPdfEngine.java Outdated
Comment thread jablib/src/main/java/org/jabref/logic/ocr/OcrMyPdfEngine.java Outdated
Comment thread jablib/src/main/java/org/jabref/logic/ocr/OcrResult.java Outdated
Comment thread jablib/src/main/java/org/jabref/logic/ocr/OcrMyPdfEngine.java Outdated
@Siedlerchr

Copy link
Copy Markdown
Member

can you add some more info the PR, like how and where to install ocrmypdf so it works?

@ZiadAbdElFatah

ZiadAbdElFatah commented May 12, 2026

Copy link
Copy Markdown
Collaborator Author

can you add some more info the PR, like how and where to install ocrmypdf so it works?

Yeah, for sure, all of this stuff will be added. This PR is only the start of the project, we just want to test the feature and make sure it's working.
If you want to try it, you can download OCRmyPDF from here, but I haven't implemented the GUI part yet, so there is no button for perform OCR yet.

@ZiadAbdElFatah ZiadAbdElFatah requested a review from Siedlerchr May 12, 2026 07:21
Comment thread jabgui/src/main/java/org/jabref/gui/linkedfile/OcrLinkedFileAction.java Outdated
Comment thread jabgui/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditorViewModel.java Outdated

@subhramit subhramit left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great progress, Ziad!
Some comments from my side.

Comment on lines +301 to +302
public TaskExecutor getTaskExecutor() {
return taskExecutor;

@subhramit subhramit May 13, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inject downstream from JabRefGUI via constructors. See AIService for example.

JabRefGUI.aiService = new AiService(
preferences.getAiPreferences(),
preferences.getFilePreferences(),
preferences.getCitationKeyPatternPreferences(),
dialogService,
taskExecutor);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the "View" you use; @Inject TaskExecutor taskExecutor, then when you create a view model, pass it in the constructor

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it not be better to do it the OCRService way as an analogue?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You know, I was thinking, should we make an OCRService or not?

I have an idea to create an engine only when it’s needed. So the action will look (in the future) to the selected OCR engine and then different class will be created.

But IDK. The reason I propose this idea is to be more decentralized and also to not having a new injected dependency in many UI components. Because with AiService I had to put it in a lot of places, because some specific component C depends on B, and B depends on A. But then B and A are instantiated in many places, so in the end AiService was in a lot of constructors

@subhramit subhramit May 14, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. In my mind, I was trying to see the symmetry between OCR and existing AI (the taskexecutor, dialogservice, prefs passed via constructors) but I think what you propose is better and more loosely coupled.

Looping @calixtus in as well as this might be a decision costly to change if we ever have to move towards a uniform model.

Comment thread jabgui/src/main/java/org/jabref/gui/linkedfile/OcrLinkedFileAction.java Outdated
Comment thread jabgui/src/main/java/org/jabref/gui/linkedfile/OcrLinkedFileAction.java Outdated
Comment thread jabgui/src/main/java/org/jabref/gui/linkedfile/OcrLinkedFileAction.java Outdated
Comment thread jabgui/src/main/java/org/jabref/gui/linkedfile/OcrLinkedFileAction.java Outdated
Comment thread jablib/src/main/java/org/jabref/logic/ocr/OcrMyPdfEngine.java Outdated
Comment thread jabgui/src/main/java/org/jabref/gui/linkedfile/OcrLinkedFileAction.java Outdated
Comment thread jablib/src/main/java/org/jabref/logic/ocr/OcrMyPdfEngine.java Outdated
Comment thread jablib/src/main/java/org/jabref/logic/ocr/OcrMyPdfEngine.java Outdated
// We have to put Entry Editor Previous before, because otherwise the decrease font size is found first
ENTRY_EDITOR_PREVIOUS_PANEL_2("Entry editor, previous panel 2", Localization.lang("Entry editor, previous panel 2"), "shortcut+MINUS", KeyBindingCategory.VIEW),
DELETE_ENTRY("Delete entry", Localization.lang("Delete entry"), "DELETE", KeyBindingCategory.BIBTEX),
PERFORM_OCR("Perform OCR", Localization.lang("Perform OCR"), "", KeyBindingCategory.FILE),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should have an appropriate shortcut. Pinging @Siedlerchr for suggestions.

Comment thread jablib/src/main/java/org/jabref/logic/ocr/OcrMyPdfEngine.java Outdated
@ZiadAbdElFatah ZiadAbdElFatah requested a review from InAnYan May 19, 2026 21:12
@github-actions

Copy link
Copy Markdown
Contributor

Your pull request conflicts with the target branch.

Please merge with your code. For a step-by-step guide to resolve merge conflicts, see https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-using-the-command-line.

Comment thread jablib/src/main/java/org/jabref/logic/ocr/OcrMyPdfEngine.java

@InAnYan InAnYan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you only need to run openrewrite, fix changelog conflict and address subhramit's coments. Overall, I think the PR is ready to go!

@ZiadAbdElFatah

Copy link
Copy Markdown
Collaborator Author

Sorry I was out of home today and yesterday and didn't have my laptop.
Tomorrow morning I am going to resolve the merge conflicts and address the comments.
The openrewrite command produce errors.

Comment thread jabgui/src/main/java/org/jabref/gui/linkedfile/OcrLinkedFileAction.java Outdated
Comment thread jabgui/src/main/java/org/jabref/gui/linkedfile/OcrLinkedFileAction.java Outdated
@github-actions github-actions Bot added status: no-bot-comments and removed status: changes-required Pull requests that are not yet complete labels May 22, 2026
subhramit
subhramit previously approved these changes May 23, 2026

@subhramit subhramit left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@subhramit subhramit enabled auto-merge May 23, 2026 08:31
@subhramit subhramit added this pull request to the merge queue May 23, 2026
@github-actions github-actions Bot added the status: to-be-merged PRs which are accepted and should go into the merge-queue. label May 23, 2026
Merged via the queue into JabRef:main with commit 88c295d May 23, 2026
53 checks passed
f0restron07 pushed a commit to f0restron07/jabref that referenced this pull request May 24, 2026
* Initial implementation for OCRmyPDF

* Addressed the review comments

* Used pre-existing StreamGobbler for BufferedReader

* Reomved unused variables

* Reformated the code to meet JabRef's code guidelines

* Added GUI to perform OCR

* Added localized messages

* Addressed the review comments

* Reverted unintended change

* Addressed the review comments

* Solved checkstyle failing check

* Added linking the new OCRed file to the used entry

* Addressed the review commits

* Added localized string to JabRef_en.preperties

* Added check for OCRMYPDF availability

* Added a comment for readability

* Reduced the time of checking the avaialabilty of OCRmyPDF

* Added --skip-text to handle partial searchable pdfs

* Update jabgui/src/main/java/org/jabref/gui/linkedfile/OcrLinkedFileAction.java

Co-authored-by: Ruslan <ruslanpopov1512@gmail.com>

* Apply suggestion from @InAnYan

Co-authored-by: Ruslan <ruslanpopov1512@gmail.com>

* Extracted the wait time in a single variable

* Apply suggestion from @InAnYan

* Added the PDF file type for the new OCRed file

* Added some missing strings to JabRef_en.propeties

* Fix comment formatting for LinkedFile constructor

* Addressed some openrewrite comments

* Added a changelog entry

* Link OCRed file to entries

* Improve OCRed file linking

* Remove unintended file

* Address review comments

* Fix comment formatting in LinkedFile constructor

* Fix comment formatting in LinkedFile constructor

* Address review comment

* fix(ocr): fix failure message

---------

Co-authored-by: Ruslan <ruslanpopov1512@gmail.com>
Siedlerchr added a commit that referenced this pull request May 25, 2026
* upstream/main:
  Add github-actions output format to jabkit check (#15789)
  Fixes of some nullaway warnings (#15792)
  Citations: Double click on entry should add and focus it (#15624)
  fix(ai): hide LLM varians if AI is disabled (#15812)
  Initial implementation for OCRmyPDF (#15712)
  fix(null): fix nullable warnings in CSLAdapter (#15803)
  Chore(deps): Bump com.autonomousapps:dependency-analysis-gradle-plugin (#15808)
  Chore(deps): Bump com.autonomousapps:dependency-analysis-gradle-plugin (#15809)
  New translations jabref_en.properties (Italian) (#15807)
  New Crowdin updates (#15796)
  Chore(deps): Bump com.autonomousapps:dependency-analysis-gradle-plugin (#15802)
  Chore(deps): Bump org.openrewrite.recipe:rewrite-recipe-bom (#15800)
  Chore(deps): Bump org.openrewrite.rewrite from 7.32.2 to 7.33.0 (#15801)
  Chore(deps): Bump com.autonomousapps:dependency-analysis-gradle-plugin (#15795)
  Chore(deps): Bump com.autonomousapps:dependency-analysis-gradle-plugin (#15794)
  Chore(deps): Bump jablib/src/main/resources/csl-styles (#15793)
  fix: remove tabs and unused AI exports (#15791)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants