-
-
Save hchoroomi/1367294 to your computer and use it in GitHub Desktop.
For the Instagram Challenge - Unshredder
This file contains hidden or 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
require 'rmagick' | |
include Magick | |
shredded = ImageList.new "TokyoPanoramaShredded.png" # the original source | |
ROWS = shredded.rows # number of lines of pixes | |
working = [] # a working array of images | |
def strip_width | |
32 | |
end | |
# pixel distance is calculated using the Euclidean distance of the 2 pixels | |
# assuming the RGB is xyz | |
def dist(p1,p2) | |
red, green, blue = p1.red - p2.red, p1.green - p2.green, p1.blue - p2.blue | |
Math.sqrt((red*red) + (green*green) + (blue*blue)) | |
end | |
# compare pixel distances between the right-most pixel column of shred1 with | |
# the left-most pixel column of shred2 | |
def compare_shreds(shred1, shred2) | |
distances = [] | |
ROWS.times do |n| # for every pixel in a narrow strip | |
pixel1 = shred1.pixel_color(strip_width-1,n) | |
pixel2 = shred2.pixel_color(0,n) | |
distances << dist(pixel1, pixel2) | |
end | |
distances.inject{|sum,x| sum + x }/ROWS # find the mean | |
end | |
# crop individual shreds into a temporary working image list | |
(shredded.columns/strip_width).times do |n| | |
working << shredded.excerpt(n*strip_width,0,strip_width,shredded.rows) | |
end | |
sequence = [0] # working sequence, starting at 0 but can start at any number | |
pic_break = 0 # to store the place where the sequence breaks | |
# iterate through every shred to find correct sequence | |
working.size.times do | |
averages = [] | |
working.size.times do |n| # compare this shred with every other shred | |
averages << compare_shreds(working[sequence.last], working[n]) | |
end | |
# the next shred should be the one with the left-most pixel column the | |
# closest pixel distance from the right-most pixel column of the current shred | |
next_number = averages.index(averages.min) | |
if next_number == sequence.last # if the next shred is the same as this shred | |
pic_break = sequence.count # this is where the image break is | |
sequence << averages.find_index(averages.sort[1]) # use the next closest | |
else | |
sequence << next_number | |
end | |
end | |
final_sequence = sequence[pic_break..sequence.count] + sequence[1..pic_break-1] | |
final_imagelist = ImageList.new | |
final_sequence.each do |seq| | |
final_imagelist << working[seq] | |
end | |
final_imagelist.append(false).display # display the image |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment