Last commit not found
# Copyright (c) 2013 by Miguel Grinberg | |
# | |
# Permission is hereby granted, free of charge, to any person obtaining a copy | |
# of this software and associated documentation files (the "Software"), to deal | |
# in the Software without restriction, including without limitation the rights | |
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
# copies of the Software, and to permit persons to whom the Software is furnished | |
# to do so, subject to the following conditions: | |
# | |
# The above copyright notice and this permission notice shall be included in all | |
# copies or substantial portions of the Software. | |
# | |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | |
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | |
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
import optparse | |
from PIL import Image, ImageSequence | |
matrices = { | |
'true': [ [ 0.299, 0.587, 0.114, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0.299, 0.587, 0.114 ] ], | |
'mono': [ [ 0.299, 0.587, 0.114, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0.299, 0.587, 0.114, 0.299, 0.587, 0.114 ] ], | |
'color': [ [ 1, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0, 0, 0, 1 ] ], | |
'halfcolor': [ [ 0.299, 0.587, 0.114, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0, 0, 0, 1 ] ], | |
'optimized': [ [ 0, 0.7, 0.3, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0, 0, 0, 1 ] ], | |
} | |
def make_anaglyph(left, right, color, path): | |
width, height = left.size | |
leftMap = left.load() | |
rightMap = right.load() | |
m = matrices[color] | |
for y in range(0, height): | |
for x in range(0, width): | |
r1, g1, b1 = leftMap[x, y] | |
r2, g2, b2 = rightMap[x, y] | |
leftMap[x, y] = ( | |
int(r1*m[0][0] + g1*m[0][1] + b1*m[0][2] + r2*m[1][0] + g2*m[1][1] + b2*m[1][2]), | |
int(r1*m[0][3] + g1*m[0][4] + b1*m[0][5] + r2*m[1][3] + g2*m[1][4] + b2*m[1][5]), | |
int(r1*m[0][6] + g1*m[0][7] + b1*m[0][8] + r2*m[1][6] + g2*m[1][7] + b2*m[1][8]) | |
) | |
left.save(path) | |
def make_stereopair(left, right, color, path): | |
width, height = left.size | |
leftMap = left.load() | |
rightMap = right.load() | |
pair = Image.new('RGB', (width * 2, height)) | |
pairMap = pair.load() | |
for y in range(0, height): | |
for x in range(0, width): | |
pairMap[x, y] = leftMap[x, y] | |
pairMap[x + width, y] = rightMap[x, y] | |
if color == 'mono': | |
pair = pair.convert('L') | |
pair.save(path) | |
def make_wiggle3d(left, right, color, path): | |
if color == 'mono': | |
left = left.convert('L') | |
right = right.convert('L') | |
#writeGif(path, [left, right], 0.1, True, False, 0, False, 2) | |
left.save(path, save_all=True, append_images=[right], duration=0.1, loop=0, | |
dispose=2) | |
def parse_arguments(): | |
parser = optparse.OptionParser(usage = 'usage: %prog [options] left_image right_image stereo_image') | |
group = optparse.OptionGroup(parser, "Stereo image options") | |
group.add_option('-a', '--anaglyph', | |
action = 'store_const', const = 'anaglyph', dest = 'type', default = 'anaglyph', | |
help = 'generate a stereo anaglyph (default)') | |
group.add_option('-p', '--parallel', | |
action = 'store_const', const = 'parallel', dest = 'type', | |
help = 'generate a parallel viewing stereo pair') | |
group.add_option('-x', '--crossed', | |
action = 'store_const', const = 'crossed', dest = 'type', | |
help = 'generate a crossed viewing stereo pair') | |
group.add_option('-w', '--wiggle', | |
action = 'store_const', const = 'wiggle', dest = 'type', | |
help = 'generate a "Wiggle 3D" animated GIF file') | |
parser.add_option_group(group) | |
group = optparse.OptionGroup(parser, "Color options") | |
group.add_option('-t', '--true', | |
action = 'store_const', const = 'true', dest = 'color', | |
help = 'generate a true color picture') | |
group.add_option('-m', '--mono', | |
action = 'store_const', const = 'mono', dest = 'color', | |
help = 'generate a monochrome picture') | |
group.add_option('-c', '--color', | |
action = 'store_const', const = 'color', dest = 'color', | |
help = 'generate a color picture') | |
group.add_option('-f', '--halfcolor', | |
action = 'store_const', const = 'halfcolor', dest = 'color', | |
help = 'generate a half color picture') | |
group.add_option('-o', '--optimized', | |
action = 'store_const', const = 'optimized', dest = 'color', default = 'optimized', | |
help = 'generate an optimized color picture (default)') | |
parser.add_option_group(group) | |
group = optparse.OptionGroup(parser, "Other options") | |
group.add_option('-r', '--resize', | |
action = 'store', type = 'int', dest = 'size', default = 0, | |
help = 'resize image to the given width (height is automatically calculated to preserve aspect ratio)') | |
parser.add_option_group(group) | |
options, args = parser.parse_args() | |
if len(args) != 3: | |
parser.error('wrong number of arguments') | |
leftImage = Image.open(args[0]) | |
pixelMap = leftImage.load() | |
rightImage = Image.open(args[1]) | |
if leftImage.size != rightImage.size: | |
parser.error('left and right images must have the same size') | |
if options.size > 0: | |
width, height = leftImage.size | |
leftImage = leftImage.resize((options.size, options.size * height / width), Image.ANTIALIAS) | |
rightImage = rightImage.resize((options.size, options.size * height / width), Image.ANTIALIAS) | |
return options, leftImage, rightImage, args[2] | |
def main(): | |
options, leftImage, rightImage, stereoPath = parse_arguments() | |
if options.type == 'anaglyph': | |
make_anaglyph(leftImage, rightImage, options.color, stereoPath) | |
elif options.type == 'parallel': | |
make_stereopair(leftImage, rightImage, options.color, stereoPath) | |
elif options.type == 'crossed': | |
make_stereopair(rightImage, leftImage, options.color, stereoPath) | |
elif options.type == 'wiggle': | |
make_wiggle3d(leftImage, rightImage, options.color, stereoPath) | |
if __name__ == '__main__': | |
main() |