[Image-SIG] GeoTIFF? (and patch)
Greg Couch
gregc@cgl.ucsf.EDU
Wed, 18 Apr 2001 17:00:00 -0700 (PDT)
Here's an alternative patch to add image resolution and several other
TIFF tags to TIFF files. Here you would add various entries to the
Image.save's options parameter to place them in a TIFF file. The ones
I added are: "resolution unit", "resolution", "x resolution", "y resolution",
"software", "date time", "artist", and "copyright". TIFF images already
supported an image "description" option. The resolutions are correctly
written as TIFF rational values.
Please cc any replies directly to me as I do not normally read this
mailing list.
Greg Couch
UCSF Computer Graphics Lab
gregc@cgl.ucsf.edu
===================================================================
RCS file: RCS/TiffImagePlugin.py,v
retrieving revision 1.1
diff -c -r1.1 TiffImagePlugin.py
*** TiffImagePlugin.py 2001/04/18 21:40:09 1.1
--- TiffImagePlugin.py 2001/04/18 23:54:25
***************
*** 66,77 ****
--- 66,84 ----
SAMPLESPERPIXEL = 277
ROWSPERSTRIP = 278
STRIPBYTECOUNTS = 279
+ X_RESOLUTION = 282
+ Y_RESOLUTION = 283
PLANAR_CONFIGURATION = 284
+ RESOLUTION_UNIT = 296
+ SOFTWARE = 305
+ DATE_TIME = 306
+ ARTIST = 315
PREDICTOR = 317
COLORMAP = 320
EXTRASAMPLES = 338
SAMPLEFORMAT = 339
JPEGTABLES = 347
+ COPYRIGHT = 33432
IPTC_NAA_CHUNK = 33723 # newsphoto properties
PHOTOSHOP_CHUNK = 34377 # photoshop properties
***************
*** 313,318 ****
--- 320,328 ----
if tag == STRIPOFFSETS:
stripoffsets = len(directory)
typ = 4 # to avoid catch-22
+ elif tag in (X_RESOLUTION, Y_RESOLUTION):
+ # identify rational data fields
+ typ = 5
else:
typ = 3
for v in value:
***************
*** 329,335 ****
elif len(data) < 4:
append((tag, typ, len(value), data + (4-len(data))*"\0", ""))
else:
! append((tag, typ, len(value), o32(offset), data))
offset = offset + len(data)
if offset & 1:
offset = offset + 1 # word padding
--- 339,348 ----
elif len(data) < 4:
append((tag, typ, len(value), data + (4-len(data))*"\0", ""))
else:
! count = len(value)
! if typ == 5:
! count = count / 2 # adjust for rational data field
! append((tag, typ, count, o32(offset), data))
offset = offset + len(data)
if offset & 1:
offset = offset + 1 # word padding
***************
*** 551,556 ****
--- 564,579 ----
"LAB": ("LAB", 8, 1, (8,8,8), None),
}
+ def _cvt_res(value):
+ # convert value to TIFF rational number -- (numerator, denominator)
+ if type(value) in (type([]), type(())):
+ assert(len(value) % 2 == 0)
+ return value
+ if type(value) == type(1):
+ return (value, 1)
+ value = float(value)
+ return (int(value * 65536), 65536)
+
def _save(im, fp, filename):
try:
***************
*** 566,573 ****
--- 589,626 ----
ifd[IMAGEWIDTH] = im.size[0]
ifd[IMAGELENGTH] = im.size[1]
+ # additions written by Greg Couch, gregc@cgl.ucsf.edu
+ # inspired by image-sig posting from Kevin Cazabon, kcazabon@home.com
+ if hasattr(im, 'tag'):
+ # preserve tags from original TIFF image file
+ for key in (RESOLUTION_UNIT, X_RESOLUTION, Y_RESOLUTION):
+ if im.tag.tagdata.has_key(key):
+ ifd[key] = im.tag.tagdata.get(key)
if im.encoderinfo.has_key("description"):
ifd[IMAGEDESCRIPTION] = im.encoderinfo["description"]
+ if im.encoderinfo.has_key("resolution"):
+ ifd[X_RESOLUTION] = ifd[Y_RESOLUTION] \
+ = _cvt_res(im.encoderinfo["resolution"])
+ if im.encoderinfo.has_key("x resolution"):
+ ifd[X_RESOLUTION] = _cvt_res(im.encoderinfo["x resolution"])
+ if im.encoderinfo.has_key("y resolution"):
+ ifd[Y_RESOLUTION] = _cvt_res(im.encoderinfo["y resolution"])
+ if im.encoderinfo.has_key("resolution unit"):
+ unit = im.encoderinfo["resolution unit"]
+ if unit == "inch":
+ ifd[RESOLUTION_UNIT] = 2
+ elif unit == "cm" or unit == "centimeter":
+ ifd[RESOLUTION_UNIT] = 3
+ else:
+ ifd[RESOLUTION_UNIT] = 1
+ if im.encoderinfo.has_key("software"):
+ ifd[SOFTWARE] = im.encoderinfo["software"]
+ if im.encoderinfo.has_key("date time"):
+ ifd[DATE_TIME] = im.encoderinfo["date time"]
+ if im.encoderinfo.has_key("artist"):
+ ifd[ARTIST] = im.encoderinfo["artist"]
+ if im.encoderinfo.has_key("copyright"):
+ ifd[COPYRIGHT] = im.encoderinfo["copyright"]
if bits != (1,):
ifd[BITSPERSAMPLE] = bits