Skip to content

Instantly share code, notes, and snippets.

@minikomi
Created November 14, 2011 07:32
Show Gist options
  • Save minikomi/1363448 to your computer and use it in GitHub Desktop.
Save minikomi/1363448 to your computer and use it in GitHub Desktop.
Instagram Deshredder
#Takes 2 arguments at command line: filename, shred width.
def unshred(img_name, shred_width):
image = Image.open(img_name)
data = image.getdata()
img_w, img_h = image.size
def get_pixel_value(x, y):
pixel = data[y * img_w + x]
return pixel
def avg_list(a):
return (sum(a, 0.0) / len(a))
def compare_pix(l_pix,r_pix):
return sqrt(sum(map(
lambda x: (log((x[0]+1)/256.0, 10.0) - log((x[1]+1)/256.0, 10.0))**2,
zip(l_pix[0:3], r_pix[0:3])
)))
number_of_columns = img_w / shred_width
left_edges = map(lambda x: x * shred_width, xrange(number_of_columns))
right_edges = map(lambda x: ((x+1) * shred_width)-1, xrange(number_of_columns))
def compare_column(l,r):
# Compares two columns of pixels - using log to offset highlights (thanks!) ;)
# Gives them a score.
score = 0.0
for y in xrange(img_h):
l_pixel = get_pixel_value(l,y)
r_pixel = get_pixel_value(r,y)
score += compare_pix(l_pixel, r_pixel)
return score
# compare each right edge to each left edge in turn & get a score
score_joins = []
for left in left_edges:
forleft = []
for right in right_edges:
if left_edges.index(left) == right_edges.index(right):
forleft.append(True)
else:
score = compare_column(left,right)
score_joins.append([score,left_edges.index(left),right_edges.index(right)])
# sort results of by score
sorted_scores = sorted(score_joins, key = lambda x: x[0])
def ordershred(order):
# Takes an array of sorted edges, checks for next left or right
# edge with the lowest score.
if len(order) == number_of_columns:
return order
else:
for x in sorted_scores:
if x[2] == order[0]:
sorted_scores.remove(x)
elif x[1] == order[-1]:
sorted_scores.remove(x)
cursor = 0
while cursor < len(sorted_scores):
l_index = sorted_scores[cursor][1]
r_index = sorted_scores[cursor][2]
if l_index == order[0]:
return ordershred([r_index] + order)
break
elif r_index == order[-1]:
return ordershred(order + [l_index])
break
else:
cursor += 1
raise Exception, "Couldn't find edge combination"
# Seed order shred with first 2 edges in shred-joins sorted by score.
final = ordershred([sorted_scores[0][2], sorted_scores[0][1]])
# Build image based on final sorting.
unshredded = Image.new("RGB", image.size)
for i in final:
shred = final[i]
x1, y1 = shred_width * shred, 0
x2, y2 = x1 + shred_width, image.size[1]
source_region = image.crop((x1, y1, x2, y2))
destination_point = (i * shred_width, 0)
unshredded.paste(source_region, destination_point)
i+=1
unshredded.save("unshredded.png", "PNG")
if __name__ == "__main__":
import sys
from math import log
from math import sqrt
from PIL import Image
unshred(sys.argv[1], int(sys.argv[2]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment