Changeset 363 for pkpgcounter/trunk

Show
Ignore:
Timestamp:
08/16/06 01:12:57 (18 years ago)
Author:
jerome
Message:

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

Location:
pkpgcounter/trunk
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • pkpgcounter/trunk/NEWS

    r343 r363  
    2222pkpgcounter News : 
    2323 
     24  * 1.84alpha : 
     25   
     26    - Added initial support for the computation of ink coverage. 
     27      See python analyzer.py --help for details. The ame command 
     28      line options work for pkpgcounter, although it's not 
     29      documented yet. 
     30     
    2431  * 1.83 : 
    2532   
  • pkpgcounter/trunk/pkpgpdls/analyzer.py

    r358 r363  
    2626 
    2727import sys 
     28import os 
    2829import tempfile 
    2930 
    3031import version, pdlparser, postscript, pdf, pcl345, pclxl, \ 
    3132       escp2, dvi, tiff, ooo, zjstream 
    32  
     33import inkcoverage 
    3334 
    3435class AnalyzerOptions : 
     
    7172                self.closeFile() 
    7273            return size 
     74             
     75    def getInkCoverage(self, colorspace=None, resolution=None) : 
     76        """Extracts the percents of ink coverage from the input file.""" 
     77        result = None 
     78        cspace = colorspace or self.options.colorspace 
     79        res = resolution or self.options.resolution 
     80        if (not cspace) or (not res) : 
     81            raise ValueError, "Invalid colorspace (%s) or resolution (%s)" % (cspace, res) 
     82        self.openFile() 
     83        try : 
     84            pdlhandler = self.detectPDLHandler() 
     85        except pdlparser.PDLParserError, msg :     
     86            self.closeFile() 
     87            raise pdlparser.PDLParserError, "Unknown file format for %s (%s)" % (self.filename, msg) 
     88        else : 
     89            try : 
     90                tiffname = self.convertToTiffMultiPage24NC(pdlhandler) 
     91                result = inkcoverage.getInkCoverage(tiffname, cspace) 
     92                try : 
     93                    os.remove(tiffname) 
     94                except OSError : 
     95                    sys.stderr.write("Problem when trying to remove temporary file %s\n" % tiffname) 
     96            finally :     
     97                self.closeFile() 
     98        return result 
     99         
     100    def convertToTiffMultiPage24NC(self, handler) :     
     101        """Converts the input file to TIFF format, X dpi, 24 bits per pixel, uncompressed. 
     102           Returns a temporary filename which names a file containing the TIFF datas. 
     103           The temporary file has to be deleted by the caller. 
     104        """    
     105        self.infile.seek(0) 
     106        (handle, filename) = tempfile.mkstemp(".tmp", "pkpgcounter")     
     107        os.close(handle) 
     108        handler.convertToTiffMultiPage24NC(filename, self.options.resolution) 
     109        return filename 
    73110         
    74111    def openFile(self) :     
     
    180217                            dest="colorspace", 
    181218                            type="cichoice", 
    182                             cichoices=["bw", "cmyk", "cmy", "all"], 
    183                             help="Activate the computation of ink usage, and defines the colorspace to use. Supported values are 'BW', 'CMYK', 'CMY' and 'ALL'.") 
     219                            cichoices=["bw", "rgb", "cmyk", "cmy"], 
     220                            help="Activate the computation of ink usage, and defines the colorspace to use. Supported values are 'BW', 'RGB', 'CMYK', and 'CMY'.") 
    184221    parser.add_option("-r", "--resolution",  
    185222                            type="int",  
     
    201238                try : 
    202239                    parser = PDLAnalyzer(arg, options) 
    203                     totalsize += parser.getJobSize() 
     240                    if not options.colorspace : 
     241                        totalsize += parser.getJobSize() 
     242                    else : 
     243                        result = parser.getInkCoverage() 
     244                        totalsize += len(result) 
     245                        print result 
    204246                except (IOError, pdlparser.PDLParserError), msg :     
    205247                    sys.stderr.write("ERROR: %s\n" % msg) 
  • pkpgcounter/trunk/pkpgpdls/inkcoverage.py

    r361 r363  
    2828from PIL import Image 
    2929 
     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     
    3041def getPercentCMYK(img, nbpix) : 
    3142    """Extracts the percents of Cyan, Magenta, Yellow, and Black from a picture. 
     
    5162           } 
    5263         
    53 def getPercent(img, nbpix) : 
    54     """Extracts the percents per color component from a picture. 
    55        
    56        Faster without Psyco on my own machine. 
    57     """ 
    58     result = {}      
    59     bands = img.split() 
    60     for (i, bandname) in enumerate(img.getbands()) : 
    61         result[bandname] = 100.0 * (reduce(lambda current, next: current + (next[1] * next[0]), enumerate(bands[i].histogram()), 0) / 255.0) / nbpix 
    62     return result     
    63          
    64 def getPercentBlack(img, nbpix) : 
     64def getPercentBW(img, nbpix) : 
    6565    """Extracts the percents of Black from a picture, once converted to gray levels.""" 
    6666    if img.mode != "L" : 
    6767        img = img.convert("L") 
    68     return { "L" : 100.0 - getPercent(img, nbpix)["L"] } 
     68    return { "B" : 100.0 - getPercent(img, nbpix)["L"] } 
    6969     
    7070def getPercentRGB(img, nbpix) : 
     
    8282           } 
    8383     
    84 def getPercents(fname) : 
    85     """Extracts the ink percentages from an image.""" 
    86     try : 
    87         import psyco 
    88     except ImportError :     
    89         pass 
    90     else :     
    91         psyco.bind(getPercentCMYK) 
     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    """ 
    9289    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     
    93100    index = 0 
    94101    image = Image.open(fname) 
     
    96103        while 1 : 
    97104            nbpixels = image.size[0] * image.size[1] 
    98             result.append((image.size, \ 
    99                            { "BLACK" : getPercentBlack(image, nbpixels), \ 
    100                              "RGB" : getPercentRGB(image, nbpixels), \ 
    101                              "CMY" : getPercentCMY(image, nbpixels), \ 
    102                              "CMYK" : getPercentCMYK(image, nbpixels), \ 
    103                            })) 
     105            result.append({ colorspace : computation(image, nbpixels) }) 
    104106            index += 1               
    105107            image.seek(index) 
     
    110112if __name__ == "__main__" : 
    111113    # NB : length of result gives number of pages ! 
    112     print getPercents(sys.argv[1]) 
     114    print getInkCoverage(sys.argv[1], "CMYK") 
  • pkpgcounter/trunk/pkpgpdls/pdlparser.py

    r362 r363  
    8383        raise RuntimeError, "Not implemented !" 
    8484         
    85     def convertToTiffMultiPage24NC(self, outputfile, dpi) : 
     85    def convertToTiffMultiPage24NC(self, fname, dpi) : 
    8686        """Converts the input file to TIFF format, X dpi, 24 bits per pixel, uncompressed. 
    87            Writes TIFF datas to the outputfile file object. 
     87           Writes TIFF datas to the file named by fname. 
    8888        """    
    8989        raise RuntimeError, "Not implemented !" 
  • pkpgcounter/trunk/pkpgpdls/postscript.py

    r359 r363  
    177177        return self.natively() or self.throughGhostScript() 
    178178         
    179     def throughTiffMultiPage24NC(self, dpi) : 
     179    def convertToTiffMultiPage24NC(self, fname, dpi) : 
    180180        """Converts the input file to TIFF format, X dpi, 24 bits per pixel, uncompressed. 
    181            Returns percents of ink coverage and number of pages. 
     181           Writes TIFF datas to the outputfile file object. 
    182182        """    
    183         self.logdebug("Converting input datas to TIFF...") 
    184         result = None     
    185         self.infile.seek(0) 
    186         (handle, filename) = tempfile.mkstemp(".tmp", "pkpgcounter")     
    187         os.close(handle) 
    188         command = 'gs -sDEVICE=tiff24nc -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -r%i -sOutputFile="%s" -' % (dpi, filename) 
    189         try : 
    190             child = popen2.Popen4(command) 
    191             try : 
    192                 data = self.infile.read(pdlparser.MEGABYTE)     
    193                 while data : 
    194                     child.tochild.write(data) 
    195                     data = self.infile.read(pdlparser.MEGABYTE) 
    196                 child.tochild.flush() 
    197                 child.tochild.close()     
    198             except (IOError, OSError), msg :     
    199                 raise pdlparser.PDLParserError, "Problem during conversion to TIFF : %s" % msg 
    200                  
    201             child.fromchild.close() 
    202             try : 
    203                 child.wait() 
    204             except OSError, msg :     
    205                 raise pdlparser.PDLParserError, "Problem during conversion to TIFF : %s" % msg 
    206                  
    207             result = inkcoverage.getPercents(filename)     
    208         finally :     
    209             try : 
    210                 os.remove(filename) 
    211             except OSError :     
    212                 pass 
    213         return result     
     183        command = 'gs -sDEVICE=tiff24nc -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -r%i -sOutputFile="%s" -' % (dpi, fname) 
     184        child = popen2.Popen4(command) 
     185        try : 
     186            data = self.infile.read(pdlparser.MEGABYTE)     
     187            while data : 
     188                child.tochild.write(data) 
     189                data = self.infile.read(pdlparser.MEGABYTE) 
     190            child.tochild.flush() 
     191            child.tochild.close()     
     192        except (IOError, OSError), msg :     
     193            raise pdlparser.PDLParserError, "Problem during conversion to TIFF : %s" % msg 
     194             
     195        child.fromchild.close() 
     196        try : 
     197            child.wait() 
     198        except OSError, msg :     
     199            raise pdlparser.PDLParserError, "Problem during conversion to TIFF : %s" % msg 
    214200         
    215201def test() :