Skip to content

Instantly share code, notes, and snippets.

@colatkinson
Last active August 29, 2015 14:03
Show Gist options
  • Save colatkinson/e11c1d13521d885b5f64 to your computer and use it in GitHub Desktop.
Save colatkinson/e11c1d13521d885b5f64 to your computer and use it in GitHub Desktop.
from PIL import Image
from optparse import OptionParser
def key_func(arr):
# Sort the pixels by luminance
r = 0.2126*arr[0] + 0.7152*arr[1] + 0.0722*arr[2]
return r
def main():
# Parse options from the command line
parser = OptionParser()
parser.add_option("-p", "--pixels", dest="pixels",
help="use pixels from FILE", metavar="FILE")
parser.add_option("-i", "--input", dest="input", metavar="FILE",
help="recreate FILE")
parser.add_option("-o", "--out", dest="output", metavar="FILE",
help="output to FILE", default="output.png")
(options, args) = parser.parse_args()
if not options.pixels or not options.input:
raise Exception("Missing arguments. See help for more info.")
# Load the images
im1 = Image.open(options.pixels)
im2 = Image.open(options.input)
# Get the images into lists
px1 = list(im1.getdata())
px2 = list(im2.getdata())
w1, h1 = im1.size
w2, h2 = im2.size
if w1*h1 != w2*h2:
raise Exception("Images must have the same number of pixels.")
# Sort the pixels lists by luminance
px1_s = sorted(px1, key=key_func)
px2_s = sorted(px2, key=key_func)
# Create an array of nothing but black pixels
arr = [(0, 0, 0)]*w2*h2
# Loop through each value of the sorted pixels
for index, val in enumerate(px2_s):
# Find the original location of the pixel
v = px2.index(val)
# Set the value of the array at the given location to the pixel of the
# equivalent luminance from the source image
arr[v] = px1_s[index]
# Set the value of px2 to an arbitrary value outside of the RGB range
# This prevents duplicate pixel locations
# I would use "del px2[v]", but it wouldn't work for some reason
px2[v] = (512, 512, 512)
# Print the percent progress
print("%f%%" % (index/len(px2)*100))
# Save the image
im3 = Image.new('RGB', im2.size)
im3.putdata(arr)
im3.save(options.output)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment