Python IPTC ParserThis python script parse the IPTC informations contained in a photo Size 5.7 kB - File type text/python-sourceFile contents#!/usr/bin/python
# Python IPTC Parser
# By Jean-Francois Roche <jfroche@jfroche.be>
# ZPhotoSlides, Zope product
# Copyright (C) 2002-2004 Jean-Francois Roche <jfroche@jfroche.be>
# Florent Carlier <florent.carlier@insa-rennes.fr>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# $Id: iptc.py,v 2.2 2004/07/26 15:09:51 gawel Exp $'
# Based on a PHP script for IPTC parser this avoid to install PIL
import sys
from StringIO import StringIO
TagsNames = {
0x14 : 'SuplementalCategories',
0x19 : 'Keywords',
0x78 : 'Caption',
0x7A: 'CaptionWriter',
0x69: 'Headline',
0x28: 'SpecialInstructions',
0x0F: 'Category',
0x50: 'Byline',
0x55: 'BylineTitle',
0x6E: 'Credit',
0x73: 'Source',
0x74: 'CopyrightNotice',
0x05: 'ObjectName',
0x5A: 'City',
0x5F: 'ProvinceState',
0x65: 'CountryName',
0x67: 'OriginalTransmissionReference',
0x37: 'DateCreated',
0x0A: 'CopyrightFlag'
}
try:
f = False
except:
False = -1
True = 1
def i16(c,o=0):
return ord(c[o+1]) + (ord(c[o])<<8)
def i32(c,o=0):
return ord(c[o+3]) + (ord(c[o+2])<<8) + (ord(c[o+1])<<16) + (ord(c[o])<<24)
def getiptc_path(path):
file = open(path,'rb')
return getiptc(file)
def getiptc_data(data):
return getiptc(StringIO(data))
def getiptc(file):
data=file.read(1)
if(ord(data)!=0xFF):
return {}
data=file.read(1)
if(ord(data)!=0xD8):
return {}
count = 0
done = False
ok = True
_markers = {}
while(not done):
capture = False
discarded = 0
c = ord(file.read(1))
while(c!=0xFF):
discarded = discarded +1
c = ord(file.read(1))
marker = ord(file.read(1))
while(marker==0xFF):
marker = ord(file.read(1))
if (discarded != 0):
break
length = (ord(file.read(1))*256 + ord(file.read(1)))
if (length < 2):
break
if(marker == 0xC0 or marker == 0xC1 or marker == 0xC2 or marker == 0xC9 or marker==0xE0 or marker==0xE1):
pass #dont care about them
elif(marker == 0xED): # SOF1
capture = True
done = True
elif(marker == 0xDA): # SOS: Start of scan... the image itself and the last block on the file
capture = False
length = -1 # This field has no length... it includes all data until EOF
done = True
else:
capture = True
_markers[count] = {}
_markers[count]['marker'] = marker
_markers[count]['length'] = length
if (capture):
_markers[count]['data'] = file.read(length)
elif (not done):#result = @fseek($this->_fp, $length, SEEK_CUR);
file.seek(length-2,1)
count = count+1
data = 0
for key in _markers.keys():
dict = _markers[key]
if(dict['marker']==0xED):
tmpdata = StringIO(dict['data'])
signature = tmpdata.read(14)
if(signature=="Photoshop 3.0\0"):
data = dict['data']
break
if (data == 0):
return {}
pos = 14
datasize = len(data)
_markers['iptc'] = {}
while (pos < datasize):
signature = data[pos:pos+4]
if (signature != '8BIM'):
break
pos = pos + 4
types = i16(data,pos)
pos = pos + 2
strlen = ord(data[pos])
pos = pos+1
header = data[pos:pos+strlen]
pos = pos+ strlen + 1 - (strlen % 2) # The string is padded to even length, counting the length byte
length = i32(data,pos)
pos = pos+ 4
basePos = pos
if(types==0x404):
#we have iptc here!
while (pos < (datasize - 5)):
signature = i16(data,pos)
if (signature != 0x1C02):
break
pos = pos+ 2
types = ord(data[pos])
pos = pos+ 1
length = i16(data,pos)
pos = pos +2
basePos = pos
label = ''
if (TagsNames.has_key(types)):
label = TagsNames[types]
else:
label = 'IPTC_%s' % types
if(_markers['iptc'].has_key(label)):
if(type(_markers['iptc'][label])!=type([])):
tmp = _markers['iptc'][label]
_markers['iptc'][label] = []
_markers['iptc'][label].append(tmp)
_markers['iptc'][label].append(data[pos:pos+length])
else:
_markers['iptc'][label] = data[pos:pos+length]
pos = basePos + length
return _markers['iptc']
if __name__ == "__main__":
if len(sys.argv) < 2:
print 'Usage: %s files...\n' % sys.argv[0]
sys.exit(0)
for filename in sys.argv[1:]:
print getiptc_path(filename)
# print getiptc_path('/home/jfroche/exif_test.jpg')
|
Click here to get the file