root / pkpgcounter / trunk / pkpgpdls / inkcoverage.py @ 363

Revision 363, 4.0 kB (checked in by jerome, 18 years ago)

Initial support for the computation of ink coverage for PostScript?
input files.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Revision Id
Line 
1#! /usr/bin/env python
2# -*- coding: ISO-8859-15 -*-
3#
4# pkpgcounter : a generic Page Description Language parser
5#
6# (c) 2003, 2004, 2005, 2006 Jerome Alet <alet@librelogiciel.com>
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20#
21# $Id$
22#
23
24"""This modules implements the computation of ink coverage in different colorspaces."""
25
26import sys
27
28from PIL import Image
29
30def getPercent(img, nbpix) :
31    """Extracts the percents per color component from a picture.
32     
33       Faster without Psyco on my own machine.
34    """
35    result = {}     
36    bands = img.split()
37    for (i, bandname) in enumerate(img.getbands()) :
38        result[bandname] = 100.0 * (reduce(lambda current, next: current + (next[1] * next[0]), enumerate(bands[i].histogram()), 0) / 255.0) / nbpix
39    return result   
40   
41def getPercentCMYK(img, nbpix) :
42    """Extracts the percents of Cyan, Magenta, Yellow, and Black from a picture.
43     
44       PIL doesn't produce useable CMYK for our algorithm, so we use the algorithm from PrintBill.
45       Psyco speeds this function up by around 2.5 times on my computer.
46    """
47    if img.mode != "RGB" :
48        img = img.convert("RGB")
49    data = img.getdata()   
50    cyan = magenta = yellow = black = 0   
51    for (r, g, b) in data :
52        if r == g == b :
53            black += 255 - r
54        else :   
55            cyan += 255 - r
56            magenta += 255 - g
57            yellow += 255 - b
58    return { "C" : 100.0 * (cyan / 255.0) / nbpix,
59             "M" : 100.0 * (magenta / 255.0) / nbpix,
60             "Y" : 100.0 * (yellow / 255.0) / nbpix,
61             "K" : 100.0 * (black / 255.0) / nbpix,
62           }
63       
64def getPercentBW(img, nbpix) :
65    """Extracts the percents of Black from a picture, once converted to gray levels."""
66    if img.mode != "L" :
67        img = img.convert("L")
68    return { "B" : 100.0 - getPercent(img, nbpix)["L"] }
69   
70def getPercentRGB(img, nbpix) :
71    """Extracts the percents of Red, Green, Blue from a picture, once converted to RGB."""
72    if img.mode != "RGB" :
73        img = img.convert("RGB")
74    return getPercent(img, nbpix)   
75   
76def getPercentCMY(img, nbpix) :
77    """Extracts the percents of Cyan, Magenta, and Yellow from a picture once converted to RGB."""
78    result = getPercentRGB(img, nbpix)
79    return { "C" : 100.0 - result["R"],
80             "M" : 100.0 - result["G"],
81             "Y" : 100.0 - result["B"],
82           }
83   
84def getInkCoverage(fname, colorspace) :
85    """Returns a list of dictionnaries containing for each page,
86       for each color component, the percent of ink coverage on
87       that particular page.
88    """
89    result = []
90    colorspace = colorspace.upper()
91    computation = globals()["getPercent%s" % colorspace]
92    if colorspace == "CMYK" : # faster with psyco on my machine
93        try :
94            import psyco
95        except ImportError :   
96            pass
97        else :   
98            psyco.bind(computation)
99   
100    index = 0
101    image = Image.open(fname)
102    try :
103        while 1 :
104            nbpixels = image.size[0] * image.size[1]
105            result.append({ colorspace : computation(image, nbpixels) })
106            index += 1             
107            image.seek(index)
108    except EOFError :       
109        pass
110    return result
111
112if __name__ == "__main__" :
113    # NB : length of result gives number of pages !
114    print getInkCoverage(sys.argv[1], "CMYK")
Note: See TracBrowser for help on using the browser.