SHARE
TWEET

Mosaify

a guest Aug 13th, 2017 9 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # Python 2.7.7 Code, utilizing PIL
  2. # Written by Jonathan Frech, 13th, 14th of August 2017
  3.  
  4. # import Python built-in libraries
  5. import random, sys, os, time
  6.  
  7. # main function
  8. def main():
  9.     # start timer
  10.     t0 = time.time()
  11.    
  12.     # try to import PIL
  13.     try: from PIL import Image, ImageDraw
  14.     except: return "Could not import PIL (Python Imaging Library). Is it installed?\nsudo apt-get install python-pil"
  15.    
  16.     # image file has to be specified
  17.     if len(sys.argv) < 2: return "Please specify an input image file name.\nUsage: python mosaify.py <image file name> [n] [k]"
  18.    
  19.     # parameters
  20.     n, k = 5., 1.
  21.     if len(sys.argv) >= 3:
  22.         try: n = float(sys.argv[2]); 1/(n>0)
  23.         except: return "Invalid parameter n ('%s')." % sys.argv[2]
  24.     if len(sys.argv) >= 4:
  25.         try: n = float(sys.argv[3]); 1/(n>0)
  26.         except: return "Invalid parameter k ('%s')." % sys.argv[3]
  27.    
  28.     # open file
  29.     print "Reading file..."
  30.     F = sys.argv[1]
  31.     try: Img = Image.open(F)
  32.     except: return "Could not open file '%s'." % F
  33.    
  34.     # image size, new image, pixel arrays, draw
  35.     s = w, h = Img.size
  36.     img = Image.new("RGB", s)
  37.     drw = ImageDraw.Draw(img)
  38.     Pix, pix = Img.load(), img.load()
  39.    
  40.     # paramters
  41.     N, K = int(max(w, h)/n), int(max(w, h)/k)
  42.  
  43.     # foreground, background (not actually shown; used internally) 
  44.     c0, c1 = (1, 0, 0), (0, 0, 1)
  45.    
  46.     # fill new image
  47.     img.paste(c0, (0, 0, w, h))
  48.    
  49.     # all points in image, all points in 3x3 grid, function name
  50.     R = [(x, y) for x in range(w) for y in range(h)]
  51.     S = [(x, y) for x in range(-1, 2) for y in range(-1, 2)]
  52.     r = random.randint
  53.    
  54.     # return random point not in image
  55.     def P():
  56.         x, y = 0, 0
  57.         while 0<=x<w and 0<=y<h: x, y = r(-K, w+K-1), r(-K, h+K-1)
  58.         return x, y
  59.    
  60.     # draw lines
  61.     print "Drawing lines..."
  62.     for _ in range(N): drw.line(P()+P(), fill = c1)
  63.    
  64.     # flood polygons (defined by line intersections)
  65.     print "Flooding polygons..."
  66.     for x, y in R:
  67.         if pix[x, y] == c0: ImageDraw.floodfill(img, (x, y), Pix[x, y])
  68.    
  69.     # fix lines (fill with surrounding colors)
  70.     print "Fixing lines..."
  71.     for x, y in R:
  72.         if pix[x, y] == c1:
  73.             f = []
  74.             for X, Y in S:
  75.                 if 0<=X+x<w and 0<=Y+y<h and pix[X+x, Y+y] != c1: f.append((X+x, Y+y))
  76.             if len(f) > 0: pix[x, y] = pix[random.choice(f)]
  77.    
  78.     # determine file name, attempt to save
  79.     v = F.split("."); f = "%s_mosaified.%s" % (".".join(v[:-1]), v[-1]); n = 2
  80.     while os.path.exists(f): f = "%s_mosaified_%d.%s" % (".".join(v[:-1]), n, v[-1]); n += 1
  81.     try: img.save(f); print "Successfully saved image as '%s'." % f
  82.     except: return "Failed to save image as '%s'." % f
  83.    
  84.     # stop timer
  85.     t1 = time.time(); t = t1-t0
  86.     print "Took %.2f seconds." % t
  87.  
  88. # run if called as main
  89. if __name__ == "__main__":
  90.     try: m = main(); print "\033[31;91mError\033[0m: %s" % m if m else ""
  91.     except KeyboardInterrupt: print "arelessly interrupted."
RAW Paste Data
Pastebin PRO Autumn Special!
Get 40% OFF on Pastebin PRO accounts!
Top