Skip to content

New feature: Optional manual adjustment of quad#164

Closed
PhilLab wants to merge 16 commits into
pynicolas:mainfrom
PhilLab:ph/edit_screen
Closed

New feature: Optional manual adjustment of quad#164
PhilLab wants to merge 16 commits into
pynicolas:mainfrom
PhilLab:ph/edit_screen

Conversation

@PhilLab
Copy link
Copy Markdown
Contributor

@PhilLab PhilLab commented Apr 19, 2026

This feature branch adds an optional quad-editing screen so users can make targeted corrections without abandoning the automation-first workflow.
The automatic quad detection is world-class, but users occasionally encounter problematic images - creased pages, atypical aspect ratio or cluttered backgrounds. Right now there is no way to recover from that.

The feature is off by default and is gated behind a setting. Nothing in the existing flow changes unless the user explicitly enables it. When enabled, a single new button appears on the DocumentScreen. This matches the project's philosophy of keeping the default experience fully automatic while giving power users an escape hatch.

There is also a concrete benefit for the intent-based Nextcloud integration: an intent extra lets the host app request the edit functionality temporarily. Nextcloud's built-in scanner exposes quad manipulation as a core feature. Matching that capability increases the chances of FairScan becoming the default scanning option there.

Tickets: #72, #59

Features

  • Move corners and edges of the quad.
  • A loupe for precise placement, with visualization of the page border and a striped pattern for areas outside the page. The loupe disappears after lifting the finger with a short delay so you can confirm the final position.
  • Undo/redo history for corner and edge movements. History is cleared when leaving the screen.
  • "Report" button in the overflow menu to share problematic images with the maintainer.
  • If the automatic page detection fails to find any document (and the feature toggle is ON), the page is stored as full image. This allows quad editing and also reporting these types of most problematic images to the maintainer.
  • Supports user-defined page rotation.
  • Supports landscape mode.
  • An intent extra to enable the edit screen from a host app (relevant for the Nextcloud integration).
portrait
quad.editing.screen.recording.mp4
landscape

Note 1: Merge conflicts

This branch is based on an older commit of main, so there are non-trivial merge conflicts with the current main branch. That is also why the screen is called EditPage and the setting is labelled "Enable manual image editing" - the intent was to keep it open for other manual edits such as color correction, which has since been added elsewhere. I would like to discuss the feature and general approach before investing the effort to resolve those conflicts and refactor the added code.

Note 2: Button layout suggestion

The current feature branch is purely additive: the setting adds a button without rearranging anything. Now that the color-edit button from main is also there, it may be worth tidying up the row. This is a suggestion only and not yet part of the current feature branch. A possible direction:

If the setting is OFF:

  1. Show only one rotation button (it already covers all rotations).
  2. Show the color-edit button next to it with a more distinctive icon, e.g. Icons.Default.ColorLens.
two buttons

If the setting is ON:

  1. Show only one rotation button.
  2. Show the color-edit button next to it.
  3. Show the quad-edit button next to it with a descriptive icon, e.g. Icons.Default.Crop.
three buttons

Note 3: AI Coding assistance

This contribution made use of Github Copilot

PhilLab added 16 commits March 29, 2026 11:22
Also tried other means to achieve a more lenient checker, but
- variable substitution did not work
- adding multiple accepted header files would not scale with more
  contributors and more years
A scanned page can be opened from the DocumentScreen.
The source image will be shown in full, with the quad on top.
The corners and edges of the quad can be dragged.

TODO: The result of the quad manipulation is not yet stored.
Displays a magnifying glass / loupe showing a zoomed-in patch of the image
for more precise placement.

Positioning rules:
1. By default, the loupe is placed above the finger.
2. If there is not enough room above, it moves to the left of the finger.
3. If there is not enough room on the left either, it moves to the right.
If the user manually rotated the image, this must be the actual orientation
of the captured image. Hence, it makes sense to also apply the same rotation
when viewing the image in the EditPageScreen
The app philosophy is that it shall function automatically by default.
Hence, the feature for manual corrections shall not be available by
default, but easily activated by those who need it.
- Made the Confirm button a MainActionButton, with a text label
- In portrait the three buttons are in a row
- In landscape, the Undo/Redo buttons are above the Confirm button and
  all is moved to the right
- Added a right-to-left preview showing that undo/redo will be mirrored
- contentDescription and text are proper string resources
This way, the user has a direct understanding how moving the corners
affects the page cutout
… applied

EditPageScreen's confirm handler called onUpdatePageQuad() (which launches
an async coroutine for IO) and then immediately called navigation.back().
DocumentScreen would compose before the disk files were updated, reading
stale bitmaps/thumbnails.
Similar to the AboutScreen, the user can send over a problematic image to
the maintainer.
If the CV couldn't detect a page, and the optional manual image editing is
enabled, it does not show the "No document detected" error but
1. captures the image nonetheless
2. Sets the quad to the whole image
3. Directly opens the editing screen
This helps to better distinguish what will be part of the document and
what not.
- when set to true, the image editing screen is enabled for this
  invocation, regardless of the user's app setting.
- when set to false, the image editing screen is disabled for this
  invocation, regardless of the user's app setting.
- when the extra is not provided, the app's own setting is used.

This extra does not change the persisted app setting.
@PhilLab
Copy link
Copy Markdown
Contributor Author

PhilLab commented Apr 19, 2026

Manual test protocol

The feature branch also adds automated unit tests. To make sure to cover more intricate flows, this is the
explicit manual test case which I performed in addition to the typical developer testing:

  1. Check out this feature branch's parent commit on the main branch (currently: 69690d5c). Scan two pages.
  2. Check out this feature branch.
  3. Verify the two existing pages still display correctly.
  4. Verify that the first page rotates correctly.
  5. Go to Settings and enable the "Enable manual image editing" setting.
  6. Enter edit mode for the first page. Verify it respects the user-defined rotation.
  7. Adjust the quad on the first page and confirm. Verify the page now shows the updated crop.
  8. Rotate the first page. Verify it still shows the updated quad with the expected rotation applied.
  9. Enter edit mode for the first page again. Verify the rotation and quad are as expected.
  10. Open the EditPage overflow menu and tap the Report button. Verify it shares the first page's image.
  11. Enter edit mode for the second page. Verify that corner dragging, edge dragging, and the undo/redo history all work correctly.
  12. Return to the DocumentScreen and export. Verify the pages have the expected rotation and crop.
  13. Disable the setting. Verify the edit button disappears.
  14. From the fairscan-intent-sample, launch an intent without the edit extra. Scan a page, go to DocumentScreen and verify the edit button is not visible.
  15. From the fairscan-intent-sample, launch an intent with the edit extra. Verify the edit button is visible.

@pynicolas
Copy link
Copy Markdown
Owner

@PhilLab Thanks a lot for this PR and for the significant amount of work behind it. I can see the effort that went into both the implementation and the UX.

I spent some time testing it locally. While the feature is interesting, I don't think this implementation is something I can merge into FairScan.

There are a few reasons for that:

  • From a UX perspective, manual quad adjustment is a tricky interaction, and I would want to approach it differently. Getting precise and reliable corner placement is particularly challenging to get a satisfying experience.
  • The changes are quite extensive and touch many parts of the app, which makes it difficult to integrate and maintain in the long term.
  • The branch has diverged significantly from main, which would require a substantial effort to reconcile.

Even though FairScan is primarily focused on an automatic workflow, I agree that handling edge cases better is important.
I will probably revisit this kind of feature in the future.

For now, I'm going to close this PR.

Thanks again for your work and for taking the time to explore this direction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants