New feature: black and white color mode - #229
Conversation
|
Thanks a lot for your PR! |
|
I just received an email with an error:
Looks like this has been pending for a month and expired now. Is this still on your radar? |
|
It is on my radar, but I didn't manage to work on it so far. I'm sorry for that. |
|
Thanks again for this pull request! Here are my thoughts:
About the "two things unrelated to the feature":
I don't see that. Did I miss something?
Yes, but it's minor (25ms per page), so we can handle it separately. I started a new branch based on your code to:
It's not ready to be merged:
Would you like to have a look at it and tell me whether this could be a good starting point for further discussion? No rush. And sorry for the time it took me. |
|
Thanks for the review, and yes, I'd continue on your branch. Binarizing once at capture and storing it lossless is simpler than my export path and the export is fast. The dpi budget can go, your 4x gives about the same resolution at the balanced setting. I'd like to hear your reasoning on the JPEG hint. Without it, someone who exports to JPEG picks black and white for a small, crisp file and gets the opposite, with nothing telling them why. In your branch that JPEG is the 8 MP image at q75, 775 kB for a text page against about 250 kB in grayscale. Maybe you have a better solution. Side note: I find it difficult to switch between the output format as it is currently a global setting rather than an export setting for the current file. I saw that there are already open issues for that. Maybe this could somehow be solved together. If the export page allows to directly change the output format, then it could be automatically adjusted and forced to PDF when B&W is selected. Just a thought. The bolder look comes from the 2 MP step. Your branch shrinks the capture to 2 MP and interpolates it back up 4x, the PR binarized the real pixels. The threshold sits much closer to paper than to ink, so softer edges mean more ink. On a rendered 300 dpi page the strokes come out 6 to 20 % wider. With the dataset photos you won't see it, at 1024x768 nothing gets shrunk. The fix is to resize the warp to The disappearing dots at 8 pt come from the despeckle step. It drops ink below 12 px at 300 dpi, and an 8 pt period or i-dot is 7 to 10 px. If specks are only removed when there is no other ink close by, all the dots survive in my test. It takes one more connectedComponents call and on old, stained paper more specks get through. "Fetched twice": Sorry, that was my mistake. A few things I noticed in the branch:
If you want, I can push the resolution fix and the despeckle change onto your branch. |
|
Thanks for your answer. I can see that you have in mind a lot of implications for this PR. On the JPEG hint. Both black&white and JPEG are non-default choices, so I expect almost only advanced users to use such a combination and to know what they are doing. I also assume that some people may use the black&white filter for the contrast it gives, not for the reduced file size: in that case, if they actually need JPEG, the hint may be annoying. I don't have a strong opinion, though. I think you can go ahead with your PR: take what you want in my commits and add what you think makes sense. Thank you very much for your work on this topic, it's impressive! |
Implements the black and white mode from #150. Measurements are in the issue comment.
Adds
ColorMode.BLACK_AND_WHITE, selectable per page and as a default in the settings. The binarization runs on the output of the existing grayscale pipeline and adds a Sauvola threshold. PDF export embeds these pages as 1 bit per pixel with CCITT group 4, rebuilt from the original capture. Automatic detection never selects the new mode, page geometry and the other two modes are untouched, and there is no new dependency.Three things you may want to decide differently:
While measuring I also noticed two things unrelated to the feature: during export the page image was fetched twice per page, and the OCR bitmap was decoded even when no OCR language is enabled. Both are fixed in this branch, since they distorted my numbers. I can split them into a separate PR if you prefer.
Tested on a device and with
./gradlew clean license check assembleRelease.