Last active
August 29, 2015 14:03
-
-
Save colatkinson/e11c1d13521d885b5f64 to your computer and use it in GitHub Desktop.
My solution to http://codegolf.stackexchange.com/q/33172
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
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