Advertisement
Guest User

Untitled

a guest
Sep 23rd, 2017
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.81 KB | None | 0 0
  1. from PIL import Image, ImageOps
  2. from math import floor
  3. import glob, os,sys
  4.  
  5. #define parameters
  6. OUTFILE = "mosaic.jpg" #Out file name
  7. tiles_numbers_width = 50 # tile numbers in width direction, tile numbers in height direction will be determined by original image
  8. size1 =128 #The pixel numbers of square tile images,
  9. size = size1, size1
  10.  
  11. def average(im): #function to calculate average RGB values of individual Image objective
  12. width, height = im.size
  13. r = 0
  14. g =0
  15. b = 0
  16. for x in range (width):
  17. for y in range (height):
  18. tr, tg, tb = im.getpixel((x,y))
  19. r +=tr
  20. g += tg
  21. b += tb
  22. r = r/(height*width)
  23. g = g/(height*width)
  24. b = b/(height*width)
  25. return (r,g,b)
  26.  
  27. class Tiles:
  28.  
  29. def __init__(self, tiles_path):
  30. self.tiles_src_path = tiles_path
  31.  
  32. def process_tiles(self): #generate smaller image files for easy operation
  33. tiles_rgb_lib = [] #list,use [index] to access individual component
  34. name = 1
  35. print("Start to process tiles images")
  36. thumbnail_path = self.tiles_src_path + "/thumbnail"
  37. if not os.path.exists(thumbnail_path):
  38. os.makedirs(thumbnail_path)
  39. for file in os.listdir(self.tiles_src_path):
  40. infile = os.path.join(self.tiles_src_path, file)
  41. if os.path.isdir(infile):
  42. continue
  43. origi_im = Image.open(infile)
  44. im = ImageOps.fit(origi_im, size, Image.ANTIALIAS)
  45. tiles_rgb_lib.append(average(im)) #average rgb values
  46. im.save(thumbnail_path+"/"+str(name) + ".thumbnail", "JPEG")
  47. name+=1
  48. print("Tiles image process completed")
  49. return tiles_rgb_lib
  50.  
  51. class Original_Image:
  52.  
  53. def __init__(self, image_path, tiles_rgb_lib):
  54. self.original_image_path = image_path
  55. self.rgb_lib = tiles_rgb_lib
  56.  
  57. def _find_tile_index_(self, target_rgb):
  58. diff = sys.float_info.max
  59. index = 1
  60. answer = 1
  61. for (x,y,z) in self.rgb_lib:
  62. temp_diff = (2+(target_rgb[0]+x)/2/256)*(target_rgb[0]-x)*(target_rgb[0]-x) + 4*(target_rgb[1]-y)*(target_rgb[1]-y) + (2+(255-(target_rgb[0]+x)/2)/256)*(target_rgb[2]-z)*(target_rgb[2]-z)
  63. #color comparison method refered to WIKIPEDIA page "color difference"
  64. if temp_diff < diff:
  65. diff = temp_diff
  66. answer = index
  67. index += 1
  68. return answer
  69.  
  70. def generate_index_matrix(self):
  71. print("start to process orginal picture")
  72. org_im = Image.open(self.original_image_path)
  73. org_w = org_im.size[0]
  74. org_h = org_im.size[1]
  75. org_tile_size = floor(org_w/tiles_numbers_width)
  76. tiles_numbers_height = floor (org_h/org_tile_size)
  77. act_w = tiles_numbers_width*org_tile_size
  78. act_h = tiles_numbers_height*org_tile_size
  79. w_crop = (org_w - act_w)/2
  80. h_crop = (org_h - act_h)/2
  81. croped_org_im = org_im.crop((w_crop, h_crop, org_w-w_crop, org_h - h_crop))
  82. index_table = []
  83. for x in range(tiles_numbers_width):
  84. print(x)
  85. temp_array = []
  86. for y in range(tiles_numbers_height):
  87. temp_img = croped_org_im.crop((x*org_tile_size, y*org_tile_size,(x+1)*org_tile_size, (y+1)*org_tile_size))
  88. temp_rgb = average(temp_img)
  89. temp_array.append(self._find_tile_index_(temp_rgb))
  90. index_table.append(temp_array)
  91. return index_table
  92.  
  93. def compose_image(index_table, src_path): #index_table, [[per_row], per_column]
  94. if len(index_table) != tiles_numbers_width or len(index_table[0]) <= 0:
  95. print("Issue with the index_table")
  96. return
  97. print("start to make mosaic picture")
  98. img = Image.new("RGB", (size1*len(index_table), size1*len(index_table[0])))
  99. for x in range(len(index_table)):
  100. for y in range(len(index_table[0])):
  101. temp_index = index_table[x][y]
  102. temp_image = Image.open(src_path+"/thumbnail/"+str(temp_index)+".thumbnail")
  103. img.paste(temp_image, (x*size1, y*size1))
  104. img.save(OUTFILE,"JPEG")
  105.  
  106. if __name__ == '__main__':
  107. if len(sys.argv) <3:
  108. print ('Usage: %s <image> <tiles directory>\r' % (sys.argv[0],))
  109. else: #sys.argv[1] for image, sys.argv[2] for tiles source
  110. compose_image(Original_Image(sys.argv[1],Tiles(sys.argv[2]).process_tiles()).generate_index_matrix(), sys.argv[2])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement