7

Is there a tool (free software, on linux) that allows me to calculate the amount of black in a PDF file? E.g. measured in mm², or some other suitable unit?

2

Recent versions of Ghostscript have a new device available, inkcov, which can count the number of pixels for each of the color channels in CMYK space. (If the PDF uses RGB, the reported color values are computed into the appropriate CMYK valuues -- the utility cannot work in RGB directly.)

Example:

$> gs -o -  -sDEVICE=inkcov sample.pdf

Processing pages 1 through 7.
Page 1
 0.00000  0.00000  0.00000  0.02231 CMYK OK
Page 2
 0.02363  0.02363  0.02363  0.02363 CMYK OK
Page 3
 0.02527  0.02527  0.02527  0.00000 CMYK OK
Page 4
 0.03322  0.03322  0.03322  0.03322 CMYK OK
Page 5
 0.00000  0.00000  0.00000  0.03413 CMYK OK
Page 6
 0.00000  0.00000  0.00000  0.01984 CMYK OK
Page 7
 0.13274  0.13274  0.13274  0.03355 CMYK OK

The values are integers in the range from 0..1, where a value of 1 represents a 100% ink coverage (for all pixels on the page). The above result hence means:

  1. Page 1 uses no Cyan, Magenta or Yellow color. The BlacK color it uses covers 2.231 % of the page area.
  2. Page 2 uses C, M, Y and K in absolutely identical measure: the respective coverage is 2.363% of the page each. (Possibly it is a "rich gray" color value mixed by identical amounts of each ink channel.)
  3. Page 3 does not use BlacK -- but it uses C, M and Y color channels for 2.527% of the page area each. (Possibly for a mix of "non-black gray"...)
  4. Page 4 again has identical 3.332 % page coverage for each of the color channels.
  5. Pages 5 and 6 use BlacK ink only.
  6. Page 7 you now can figure out yourself....
  • Looks good so far. Is there documentation about this inkcov device somewhere? – Joachim Breitner Jul 7 '15 at 14:26
  • In English: only what I wrote here (or what others have copied from my answers. In German: search the GUUG website for the members' magazine called Uptimes. The spring edition from 2013 has a longer article by me... – Kurt Pfeifle Jul 7 '15 at 15:31
  • Thanks. I conclude that inkcov has no configuration options? (I’m not looking for anything specific, I’m just curious.) – Joachim Breitner Jul 7 '15 at 20:02
  • @JoachimBreitner: If you (a) know a little bit of PostScript, (b) read and understand this answer of mine, then you could (c) conclude that a command like gs -o - -sDEVICE=inkcov -c "currentpagedevice {exch ==only ( ) print === } forall" can tell you all about potential command line switches you could use with the inkcov device. Potential params to tweak in my next comment: – Kurt Pfeifle Jul 7 '15 at 21:17
  • ...potential tweaks could be -dDeviceGrayToK=true|false, -dUseCIEColor=true|false or -sICCOutputColors=/path/to/colorprofile.icc and then some more. But if you do not know what you do, better don't touch it for serious results! – Kurt Pfeifle Jul 7 '15 at 21:22
5

EDIT: 1. Existing tool

Searching the web, I found a tool that performs exactly the same, providing also support for many formats (doc,odt,ps,png,pdf etc.). It's called pkpgcounter and it is available in many distros (incl. Fedora & Debian) or you can easily install from source code. Learn more in their website.

Usage:

pkpgcounter --colorspace BW -r150 my_file.pdf

This will calculate the percentage of black (BW) for each page separately, with an accurate 150dpi (-r150) resolution. It also supports other colorspaces, like CMYK and RGB. Calling it without any arguments will just print the number of pages.

The nice thing is that it produces about the same results as my quickly drafted solution below (which can be easily made to support multiple colorspaces as well).

If you want to calculate the ink coverage for the whole file rather than for each page separately, you can do it with awk:

pkpgcounter --colorspace BW -r150 file.pdf | sed 's/://' | awk '{s+=$2;c++} END{print s/c}'

Output (Black percentage):

10.3758

2. Custom solution

I don't know of such a tool, but it would not be difficult to approximate the percentage of black in a PDF file, using Linux command-line tools. More specifically, using pdftopng from the xpdf suite of tools, along with the convert tool (part of ImageMagick) and some scripting with sed and awk.

I drafted a script which may be useful:

#!/usr/bin/bash
# Count black percentage in a pdf document

infile=$1
[ -z "$1" ] && { echo "Usage: $0  my_file.pdf"; exit 2; }
[ -f "$infile" ] || { echo "$infile does not exist"; exit 2; }
type pdftopng &>/dev/null || { echo "Please install pdftopng (from xpdf)"; exit 2; }
type convert &>/dev/null || { echo "Please install convert (from ImageMagick)"; exit 2; }    

# Temporary directory and files
dir="/tmp/pdf-ink-$$"
tmpfile="$dir/tmp.mpc"
tmpfile2="$dir/tmp2.mpc"

# Delete temporary files on EXIT or interrupts
trap "rm -rf $dir; exit 0" 0
trap "rm -rf $dir; exit 1" 1 2 3 15

# Create the temporary directory
mkdir "$dir"

# First step : convert pdf pages to png images - one image per page - saved at the temp directory
pdftopng -mono "$infile" "${dir}/pages"

# change to temporary directory and continue operations there
cd "$dir"


# Calc histogram for image $1
histogram() {
    # convert to temporary format for faster processing (mpc)
    convert -quiet -regard-warnings "$1" +repage "$tmpfile"
    # dither image
    convert "$tmpfile" +dither -colors 2 -colorspace gray -contrast-stretch 0 "$tmpfile2"
    # calculate histogram
    convert "$tmpfile2" -define histogram:unique-colors=true -format %c histogram:info:-    
}

# Calc percentage for histogram
hist_percent() {
    sed 's/:.*#/ /g' |   # make output parsable
    awk '{b[$3]+=$1; sum+=$1} END { OFS="\t"; for (i in b) print i, (b[i]/sum)*100 }' |   # calculate percentages
    sed 's/gray(255)/white/;s/gray(0)/black/' | column -t  # humanize output
}

# Process each page separately - then pipe histogram to awk for percentage calculation
for f in *.png; do histogram "$f"; done | hist_percent

Save it with a meaningful name like calc_pdf_ink.sh and make it executable with chmod +x calc_pdf_ink.sh. Then you can call it like this:

./calc_pdf_ink.sh myfile.pdf

Output:

white  90.3206
black  9.67944

Now, to calculate the amount of black in a specific unit, you need to multiply this percentage with the area of the printing format. E.g. for an A4 with an area of 624 cm2 , the black will cover 60,4 cm2.

For this to work, you will need the aforementioned tools, which will be probably already installed in your system (Otherwise, both xpdf and convert will be available in the repo of your distribution)

How it works:

  1. It converts the pdf file to a series of monochrome png images (one image for each page).
  2. It calculates a two-colors (black/white) histogram of each page using the convert tool
  3. The histogram of each page is then parsed with awk which adds up the black pixels for all pages, then the white pixels, and calculates the percentages of the two colors.

You may also want to place the script somewhere in your PATH (or symlink to it from your PATH), so it can be called simply by its name (calc_pdf_ink.sh file.pdf and not /path/to/script/calc_pdf_ink.sh file.pdf)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.