Hanging the NASA space travel posters in an orderly fashion

I assume that the reader is familiar with the NASA JPL Visions of the Future posters. Because all cool people know about them and only cool people read my blog.

Well after years of anticipation, I finally found an opportunity to actually put them up on my wall -as I recently relocated- and I was struck by an unforeseen problem.
How does one arrange fifteen colored posters with different dominant colors?
It really seems that the theme of this blog is answering unavailing (at least according to some) questions.

Initially we need the images to be sorted, in our case the thumbnails of the posters, which we shall retrieve with a rather crude but fully functional (as of 6/9/17) chain of commands:

curl -s https://www.jpl.nasa.gov/visions-of-the-future/ | grep "small.jpg' alt" | cut -d "'" -f 2 | xargs -I @ wget https://www.jpl.nasa.gov/visions-of-the-future/@

Ok now what?
As it turns out color sorting is not that trivial. After sufficient research, my decision was to sort by hue instead of playing with color distance (maybe this should be given a try as well).

Step one is to create a loop that iterates over jpgs and pngs in a given (by command line argument) folder using os.walk:

for (path, dirs, files) in os.walk(sys.argv[1]):
    for fname in files:
        if fname.endswith(('.jpg', '.png')):

Now using pillow (non-dead version of Python Imaging Library) we can open our images and get the RGB channels values of the pixels with getdata.
By dividing the sum with the len of the pixels, we have our median poster color, followed by a division with 255 since our conversion library prefers a range from 0-1. (thrice, once for each color channel)

meanRGB = [(float(sum(list(im.getdata(channel)))) / len(list(im.getdata(channel))))/255 for channel in range(3)]

Next, we convert this lonely pixel to HSV using colorsys, and fill a list with that and the filename of the image:


Finally, when the loops are done we can sort this list and print out the hue sorted filenames:

print '\n'.join([q[1] for q in meanHSV])

In case you were wondering:

~/py/visionssort$ ./sort.py .

Since the right arrangement for my wall is 3×5, this pattern was preferred (i.e. I couldn’t come up with a better solution):

And the final result is:

I can now hang my posters in peace, knowing that they are arranged.
Full code

Leave a Reply

Your email address will not be published. Required fields are marked *