Conditional -negate pdf file
Conditional -negate pdf file
I'm trying to convert a pdf where some pages have white text on dark background. I can successfully convert single pages using -negate, but how can I conditionally process all pages, only converting those with a dark background? IM 7.0.7-Q16 on Win 10 64bit. Many thanks.
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Conditional -negate pdf file
I think you will have to write a script loop over each image. First test for the background color such as the color of the top left corner (0,0). Depending whether it is black or white, do a magick command with the -negate if black and do the magick command without the -negate if white.
will return the color of the top left pixel. Note: depending upon if your image is binary and the type, you might get white/black or rgb(255,255,255)/rgb(0,0,0) or gray(255)/gray(0). You will have to do a test or make your condition check for all 3. If your image is not binary, then you will have to test whether the value is lighter or darker than gray(50%).
You will have to put the result into a variable and use the variable in a conditional statement to do the testing.
Pseudocode:
Sorry I am a Unix person, so one of the Windows users will have to help with the scripting.
Code: Select all
magick image.pdf[0] -format "%[pixel:u.p{0,0}]" info:
You will have to put the result into a variable and use the variable in a conditional statement to do the testing.
Pseudocode:
Code: Select all
if variable = black
convert image.pdf -negate ... image.png
else if variable = white
convert image.pdf ... image.png
end if
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Conditional -negate pdf file
CONTINUED:
What I often do is make a new variable, say, negating from the conditional test. So
Pseudocode:
Then make one command line
This way then negating = "", it does nothing and when negating = "-negate" it does the -negate. But it is the condition test that decides.
What I often do is make a new variable, say, negating from the conditional test. So
Pseudocode:
Code: Select all
if variable = black
negating = "-negate"
else if variable = white
negating = ""
end if
Code: Select all
convert image negating ... image
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Conditional -negate pdf file
A slightly different approach: convert the PDF to files in your required format. Then loop through the created images, testing each to see if it needs negating. The test might use the average intensity, assuming that the text occupies fewer pixels than the background. If it doesn't need negating, there is no need to do anything.
Depending on how you convert the PDF, you could test each image at that stage.
If you want further advice, please post the command you use, and a link to a sample input PDF.
Depending on how you convert the PDF, you could test each image at that stage.
If you want further advice, please post the command you use, and a link to a sample input PDF.
snibgo's IM pages: im.snibgo.com
Re: Conditional -negate pdf file
In a batch file I'm using:
magick convert %1 -alpha deactivate -negate -white-threshold 85%% "%~dpn1_negated%~x1"
which inverts all the pages of the input.pdf to the output.pdf
magick convert %1 -alpha deactivate -negate -white-threshold 85%% "%~dpn1_negated%~x1"
which inverts all the pages of the input.pdf to the output.pdf
- GeeMack
- Posts: 718
- Joined: 2015-12-01T22:09:46-07:00
- Authentication code: 1151
- Location: Central Illinois, USA
Re: Conditional -negate pdf file
Using IM7 offers various approaches, but you should be using just "magick" instead of "magick convert" to use its full set of features.
You can read in the PDF, then use an FX expression to check for the mean value of each page and negate any page with a mean value less than 50% without affecting pages with a mean value over 50%. Here's a sample command to try...
Code: Select all
magick input.pdf -set filename:f "%[t]_checked" ^
-channel RGB -level "%[fx:mean<0.5?100:0],%[fx:mean<0.5?0:100]%" "%[filename:f].pdf"
To use that in a BAT script you'll need to double the percent signs "%%".
Re: Conditional -negate pdf file
I'm getting an error:
convert: invalid argument for option '-level': %[fx:mean<0.5?100:0]% @ error/convert.c/ConvertImageCommand/2003.
Can fx be used to supply an argument for level? Or am I not formatting it correctly? Trying it manually on command line for now.
convert: invalid argument for option '-level': %[fx:mean<0.5?100:0]% @ error/convert.c/ConvertImageCommand/2003.
Can fx be used to supply an argument for level? Or am I not formatting it correctly? Trying it manually on command line for now.
- GeeMack
- Posts: 718
- Joined: 2015-12-01T22:09:46-07:00
- Authentication code: 1151
- Location: Central Illinois, USA
Re: Conditional -negate pdf file
Try using just "magick" instead of "magick convert". When you add "convert" to the command it will take on IM6 behavior. You need it to act like IM7 to make those inline FX expressions work.
Re: Conditional -negate pdf file
Thank you GeeMack, I'm getting close now. I have:
magick input.pdf -channel RGB -level "%%[fx:mean<0.5?100:0]%%" output.pdf
which negates only the dark pages. Only one parameter needed for level, since white point is the opposite of black point.
However, I also wanted to add -white-threshold 85%, but only for those pages that were negated. So I tried:
magick input.pdf -channel RGB -level "%%[fx:mean<0.5?100:0]%% -white-threshold "%%[fx:mean<0.5?85:100]%%" output.pdf
But this didn't work, I assume because the mean calculated at white-threshold is from the negated image, which is above 0.5?
I wondered if I could store the mean at the start somehow, I tried:
magick input.pdf -channel RGB -set option:mw "%%[mean]" -level "%%[fx:mw<0.5?100:0]%% -white-threshold "%%[fx:mw<0.5?85:100]%%" output.pdf
but I get error: magick: unable to parse expression `mw' @ error/fx.c/FxGetSymbol/1828.
Any ideas?
magick input.pdf -channel RGB -level "%%[fx:mean<0.5?100:0]%%" output.pdf
which negates only the dark pages. Only one parameter needed for level, since white point is the opposite of black point.
However, I also wanted to add -white-threshold 85%, but only for those pages that were negated. So I tried:
magick input.pdf -channel RGB -level "%%[fx:mean<0.5?100:0]%% -white-threshold "%%[fx:mean<0.5?85:100]%%" output.pdf
But this didn't work, I assume because the mean calculated at white-threshold is from the negated image, which is above 0.5?
I wondered if I could store the mean at the start somehow, I tried:
magick input.pdf -channel RGB -set option:mw "%%[mean]" -level "%%[fx:mw<0.5?100:0]%% -white-threshold "%%[fx:mw<0.5?85:100]%%" output.pdf
but I get error: magick: unable to parse expression `mw' @ error/fx.c/FxGetSymbol/1828.
Any ideas?
- GeeMack
- Posts: 718
- Joined: 2015-12-01T22:09:46-07:00
- Authentication code: 1151
- Location: Central Illinois, USA
Re: Conditional -negate pdf file
IM won't let you set a variable like that and use it inside another FX expression, but you can set a variable with the results of an entire expression, then use that variable by itself further along in the command. Try something more like this...
Code: Select all
magick input.pdf -channel RGB -set option:var1 "%%[fx:mean<0.5?100:0]" ^
-set option:var2 "%%[fx:mean<0.5?85:100]" -level "%%[var1]%%" -white-threshold "%%[var2]%%" output.pdf
Re: Conditional -negate pdf file
Ok that works now, thanks.
One last issue - the level command seems to cause a problem with the anti-aliasing. I noticed the output pdf has reduced image dimensions and file size. Not sure why?
One last issue - the level command seems to cause a problem with the anti-aliasing. I noticed the output pdf has reduced image dimensions and file size. Not sure why?
- GeeMack
- Posts: 718
- Joined: 2015-12-01T22:09:46-07:00
- Authentication code: 1151
- Location: Central Illinois, USA
Re: Conditional -negate pdf file
When IM reads in a PDF it defaults to a density of 72. Try setting the density before reading the input file, maybe 150 or 300.
Code: Select all
magick -density 300 input.pdf ... ... ... output.pdf
Re: Conditional -negate pdf file
That does it. Thanks very much for all your help.
- GeeMack
- Posts: 718
- Joined: 2015-12-01T22:09:46-07:00
- Authentication code: 1151
- Location: Central Illinois, USA
Re: Conditional -negate pdf file
Keep in mind when using FX expressions directly within an operation like...
Code: Select all
... -level "%[fx:mean<0.5?100:0] ...
Code: Select all
... -set option:var1 "%%[fx:mean<0.5?100:0]" -level "%%[var1]%%" ...