PSE Entertainment Corp
February 06, 2012, 03:02:15 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: Enjoy PSE Tunes!  They're great!
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: Python method to get information from a Tiff image  (Read 1831 times)
webmast
Guest
« on: July 04, 2009, 08:59:30 AM »

The tiff image is a very common image format.  It is the preferred format for high resolution printing and is also the most common format for Aerial and Satellite imagery.  Upon Googling the tiff standard, I was surprised by how complicated it really was.  Apparently, in 1987, all that complication seemed like a good idea.  Whatever...

Anyways, here is a Python class that provides a few pieces of information about a given tiff image.  It can easily be exended to provide more.  

One note about this code:  it utilizes Python class descriptors as a way to __set__ the tiff file before making any attempt to parse through the bytes and read a few attributes.  In addition, the code utilizes the VERY useful struct module in Python.  If you're ever required to parse some bytes, stuct is invaluable.

Code:
#PYTHON TiffInfo v1.3
#
#Copyright 2009, PSE Entertainment Corp, All Rights Reserved
#This python class will compute 4 pieces of information from a tiff image
#---ImageWidth, ImageLength, SamplesPerPixel, and ColorProfile---
#
#Usage: instantiate the TiffInfo class, set the tiff file
#then access the properties - something like...
#
#   mytiff = TiffInfo()
#   mytiff.tiff = 'path/to/some/image.tif'
#   mytiff.ColorProfile
#   mytiff.ImageLength
#   mytiff.ImageWidth
#   mytiff.ColorsPerSample
#
#
#ColorProfile will return one of the follow ICC profiles:
#   None
#   Adobe RGB (1998)
#   sRGB IEC61966-2-1
#   Kodak ProPhoto RGB
#   eciRGB v2
#   eciRGB v4
#   Other
#  
#Any error condition returns -1 as the image attributes.

import binascii, struct

class GetTiffInfo(object):
    def __set__(self,inst,tiff):
        #This is the method that gets called anytime a tiff
        #image is set.  It uses the __set__ class descriptor
        #and all internal references are based on the instance - inst.
        inst.__dict__['tiff'] = tiff
        try:
            image = open(tiff,'rb')
        except:
            inst.ColorProfile,inst.ColorsPerSample,inst.ImageLength\
            ,inst.ImageWidth = self.error()
            return
            
        #read the first 2 bytes to know "endian"
        start = image.read(2)
        endian = binascii.hexlify(start).upper()
        if endian == "4949":
            symbol = "<"
        elif endian == "4D4D":
            symbol = ">"
        else:
            inst.ColorProfile,inst.ColorsPerSample,inst.ImageLength\
            ,inst.ImageWidth = self.error()
            return

        #if the_answer isn't 42 then the file not a tiff image!
        #BTW - this IS a Douglas Adams reference.
        the_answer = image.read(2)
        the_answer = struct.unpack(symbol+'H',the_answer)[0]
        #the_answer = int(binascii.hexlify(the_answer)[0:2],16)
        if the_answer != 42:
            inst.ColorProfile,inst.ColorsPerSample,inst.ImageLength\
            ,inst.ImageWidth = self.error()
            return
        
        #Figure out where the Image File Directory is.  It can be
        #anywhere in the file believe it or not.
        dir_loc = image.read(4)
        dir_loc = struct.unpack(symbol+'L',dir_loc)[0]

        #goto that section of the file            
        image.seek(dir_loc)

        #figure out how many tags there are            
        directory_data = image.read(2)
        num_entries = struct.unpack(symbol+'H',directory_data)[0]

        #loop through the Image File Directory and look for the tags we care about
        #Width, Height, SamplesPerPixel, and ColorProfile
        for i in range(num_entries):
            a_tag = image.read(12)
            tag = struct.unpack(symbol+'HHLL',a_tag)
            #catch in case the type is SHORT
            if tag[1] == 3:
                tag = struct.unpack(symbol+'HHLHH',a_tag)
            #set the class attributes if the tag is one we care about
            if tag[0] == 256:
                inst.ImageWidth = tag[3]
            if tag[0] == 257:
                inst.ImageLength = tag[3]
            if tag[0] == 258:
                inst.ColorsPerSample = tag[2]
            if tag[0] == 34675:
                inst.ColorProfile = True
                if inst.ColorProfile == True:
                    icc_loc = tag[3]
                    icc_length = tag[2]
                    image.seek(icc_loc)
                    icc_data = image.read(icc_length)
                    struct_format = '%s%s%s' % (symbol,icc_length,'s')
                    icc_string = struct.unpack(struct_format,icc_data)[0]
                    if "Adobe RGB (1998)" in icc_string:
                        inst.ColorProfile = "Adobe RGB (1998)"
                    elif "sRGB IEC61966-2-1" in icc_string:
                        inst.ColorProfile = "sRGB IEC61966-2-1"
                    elif "ProPhoto RGB" in icc_string:
                        inst.ColorProfile = "Kodak ProPhoto RGB"
                    elif "eciRGB" in icc_string:
                        inst.ColorProfile = "eciRGB v2"
                    elif "e\0c\0i\0R\0G\0B\0" in icc_string:
                        inst.ColorProfile = "eciRGB v4"
                    else:
                        inst.ColorProfile = "Other"
            else:
                inst.ColorProfile = "None"

    def error(self):
        #This error function just resets all the tiff values
        ColorProfile = "None"
        ColorsPerSample = -1
        ImageLength = -1
        ImageWidth = -1
        return(ColorProfile,ColorsPerSample,ImageLength,ImageWidth)

class TiffInfo(object):
    #This is the interface class.  When called
    #it instantiates the GetTiffInfo() class which actually
    #does all the work.
    def __init__(self):
        self.ColorProfile = "None"
        self.ColorsPerSample = -1
        self.ImageLength = -1
        self.ImageWidth = -1
    tiff = GetTiffInfo()    
« Last Edit: May 01, 2010, 10:23:34 AM by webmaster » Report to moderator   Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.14 | SMF © 2006-2008, Simple Machines LLC Valid XHTML 1.0! Valid CSS!