Created
November 28, 2011 10:34
-
-
Save astanin/1399918 to your computer and use it in GitHub Desktop.
Uncrop a sequence of Cropped TIFFs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# Public Domain | |
""" | |
Uncrop a sequence of Cropped TIFFs[1] generated by Hugin, nona or | |
PTmender. | |
Pad images with transparent background to the minimum common extent | |
according to XPosition, YPosition tags. Images are save to uncrop/ | |
subdirectory. | |
Requirements: tiffdump and convert utilities. | |
[1]: http://wiki.panotools.org/Cropped_TIFF | |
""" | |
from sys import argv, exit | |
from os import popen, system, path, environ | |
OUTPUT_DIR = "uncrop/" | |
def usage(): | |
print path.basename(argv[0]), " image.tiff [image.tiff ...]" | |
print __doc__ | |
def readtags(tiff): | |
def readtag(fields): | |
name = fields[0] | |
type_ = fields[3] | |
types = { "(1)": int, # BYTE | |
"(2)": chr, # ASCII | |
"(3)": int, # SHORT | |
"(4)": int, # LONG | |
"(5)": float # RATIONAL | |
} | |
readfn = types.get(type_, lambda x:x) | |
vals = fields[-1].strip() | |
vals_ = [ s for s in vals[vals.find("<")+1:-1].split()] | |
vals = map(readfn, vals_) | |
val = vals[0] if len(vals) == 1 and (type_ in types.keys()) else vals | |
return (name,val) | |
lines = [ ln.strip().split(" ", 4) | |
for ln in popen("tiffdump '%s'" % tiff).readlines()[3:] ] | |
tags = [ readtag(ln) for ln in lines ] | |
return dict(tags) | |
def extent_px(tagged_pairs): | |
tops = [] | |
lefts = [] | |
bottoms = [] | |
rights = [] | |
for img,tags in tagged_pairs: | |
xpos = tags["XPosition"] | |
ypos = tags["YPosition"] | |
xdpi = tags["XResolution"] | |
ydpi = tags["YResolution"] | |
w = tags["ImageWidth"] | |
h = tags["ImageLength"] | |
l = int(round(xpos*xdpi)) | |
t = int(round(ypos*ydpi)) | |
tops.append(t) | |
lefts.append(l) | |
bottoms.append(t+h) | |
rights.append(l+w) | |
return ((min(lefts), min(tops)), (max(rights),max(bottoms))) | |
def geom(extent): | |
(x0,y0), (x1,y1) = extent | |
w = x1-x0 | |
h = y1-y0 | |
return (w,h) | |
def repage(image, tags, newgeom, newimage): | |
W, H = newgeom | |
xpos = tags["XPosition"] | |
ypos = tags["YPosition"] | |
xdpi = tags["XResolution"] | |
ydpi = tags["YResolution"] | |
w = tags["ImageWidth"] | |
h = tags["ImageLength"] | |
l = int(round(xpos*xdpi)) | |
t = int(round(ypos*ydpi)) | |
ext1 = "%dx%d" % (w+l, h+t) | |
ext2 = "%dx%d" % (W, H) | |
cmd = "convert '%s' -background none -gravity southeast -extent %s -gravity northwest -extent %s '%s'" % (image, ext1, ext2, newimage) | |
print cmd | |
system(cmd) | |
images = argv[1:] | |
if not images: | |
usage() | |
exit(0) | |
tagged = [ (img, readtags(img)) for img in images ] | |
geom = geom(extent_px(tagged)) | |
for img, tags in tagged: | |
repage(img, tags, geom, OUTPUT_DIR + img) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment