#!/usr/bin/env python
# tile_match Rel 4
# This script will try to compose source image using tiles of given dimesions from tile image (using difference mode)
# to match tiles with lowest average difference RGB values.
# Process described here:
https://www.gimplearn.net/viewtopic.php ... 651#p13651 # Created by Tin Tran
http://gimplearn.net# Comments directed to
http://gimplearn.com or
http://gimp-forum.net or
http://gimpchat.com or
http://gimpscripts.com#
# License: GPLv3
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY# without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# To view a copy of the GNU General Public License
# visit:
http://www.gnu.org/licenses/gpl.html#
#
# ------------
#| Change Log |
# ------------
# Rel 1: Initial release.
# Rel 2: Rotate 90,180,270 copies of tile image so that we get variations of different tile orientation
# Rel 3: Use random tile between 5 closes tiles for variation so that pattern isn't to repetitive
# Rel 4: Average color instead of shape match
#import string
#import Image
import random
from gimpfu import *
#from array import array
#import sys
def getKey(item):
return item[0]
def python_tt_tile_match(image, layer, tile_image, dimension):
pdb.gimp_image_undo_group_start(image)
pdb.gimp_context_push()
pdb.gimp_selection_none(image)
blur_layer = pdb.gimp_layer_new_from_drawable(layer,image)
pdb.gimp_image_insert_layer(image,blur_layer,None,0)
pdb.plug_in_pixelize(image,blur_layer,dimension)
layer = blur_layer
#duplicates tile image to work on
tile_compare_img1 = pdb.gimp_image_duplicate(tile_image)
tile_compare_img2 = pdb.gimp_image_duplicate(tile_image)
tile_compare_img3 = pdb.gimp_image_duplicate(tile_image)
tile_compare_img4 = pdb.gimp_image_duplicate(tile_image)
#make different orientations of 1
pdb.gimp_image_rotate(tile_compare_img2,ROTATE_90)
pdb.gimp_image_rotate(tile_compare_img3,ROTATE_180)
pdb.gimp_image_rotate(tile_compare_img4,ROTATE_270)
# make 5 to 8 copies of 1 to 4
tile_compare_img5 = pdb.gimp_image_duplicate(tile_compare_img1)
tile_compare_img6 = pdb.gimp_image_duplicate(tile_compare_img2)
tile_compare_img7 = pdb.gimp_image_duplicate(tile_compare_img3)
tile_compare_img8 = pdb.gimp_image_duplicate(tile_compare_img4)
#make 5 to 8 mirrors of 1 to 4
pdb.gimp_image_flip(tile_compare_img5,ORIENTATION_HORIZONTAL)
pdb.gimp_image_flip(tile_compare_img6,ORIENTATION_HORIZONTAL)
pdb.gimp_image_flip(tile_compare_img7,ORIENTATION_HORIZONTAL)
pdb.gimp_image_flip(tile_compare_img8,ORIENTATION_HORIZONTAL)
tile_compare_dis1 = pdb.gimp_display_new(tile_compare_img1)
tile_compare_dis2 = pdb.gimp_display_new(tile_compare_img2)
tile_compare_dis3 = pdb.gimp_display_new(tile_compare_img3)
tile_compare_dis4 = pdb.gimp_display_new(tile_compare_img4)
tile_compare_dis5 = pdb.gimp_display_new(tile_compare_img5)
tile_compare_dis6 = pdb.gimp_display_new(tile_compare_img6)
tile_compare_dis7 = pdb.gimp_display_new(tile_compare_img7)
tile_compare_dis8 = pdb.gimp_display_new(tile_compare_img8)
tile_layer1 = pdb.gimp_image_get_active_layer(tile_compare_img1)
tile_layer2 = pdb.gimp_image_get_active_layer(tile_compare_img2)
tile_layer3 = pdb.gimp_image_get_active_layer(tile_compare_img3)
tile_layer4 = pdb.gimp_image_get_active_layer(tile_compare_img4)
tile_layer5 = pdb.gimp_image_get_active_layer(tile_compare_img5)
tile_layer6 = pdb.gimp_image_get_active_layer(tile_compare_img6)
tile_layer7 = pdb.gimp_image_get_active_layer(tile_compare_img7)
tile_layer8 = pdb.gimp_image_get_active_layer(tile_compare_img8)
blur_layer = pdb.gimp_layer_new_from_drawable(tile_layer1,tile_compare_img1)
pdb.gimp_image_insert_layer(tile_compare_img1,blur_layer,None,0)
pdb.plug_in_pixelize(tile_compare_img1,blur_layer,dimension)
blur_layer = pdb.gimp_layer_new_from_drawable(tile_layer2,tile_compare_img2)
pdb.gimp_image_insert_layer(tile_compare_img2,blur_layer,None,0)
pdb.plug_in_pixelize(tile_compare_img2,blur_layer,dimension)
blur_layer = pdb.gimp_layer_new_from_drawable(tile_layer3,tile_compare_img3)
pdb.gimp_image_insert_layer(tile_compare_img3,blur_layer,None,0)
pdb.plug_in_pixelize(tile_compare_img3,blur_layer,dimension)
blur_layer = pdb.gimp_layer_new_from_drawable(tile_layer4,tile_compare_img4)
pdb.gimp_image_insert_layer(tile_compare_img4,blur_layer,None,0)
pdb.plug_in_pixelize(tile_compare_img4,blur_layer,dimension)
blur_layer = pdb.gimp_layer_new_from_drawable(tile_layer5,tile_compare_img5)
pdb.gimp_image_insert_layer(tile_compare_img5,blur_layer,None,0)
pdb.plug_in_pixelize(tile_compare_img5,blur_layer,dimension)
blur_layer = pdb.gimp_layer_new_from_drawable(tile_layer6,tile_compare_img6)
pdb.gimp_image_insert_layer(tile_compare_img6,blur_layer,None,0)
pdb.plug_in_pixelize(tile_compare_img6,blur_layer,dimension)
blur_layer = pdb.gimp_layer_new_from_drawable(tile_layer7,tile_compare_img7)
pdb.gimp_image_insert_layer(tile_compare_img7,blur_layer,None,0)
pdb.plug_in_pixelize(tile_compare_img7,blur_layer,dimension)
blur_layer = pdb.gimp_layer_new_from_drawable(tile_layer8,tile_compare_img8)
pdb.gimp_image_insert_layer(tile_compare_img8,blur_layer,None,0)
pdb.plug_in_pixelize(tile_compare_img8,blur_layer,dimension)
#result image
result_img = pdb.gimp_image_new(int(image.width/dimension)*dimension,int(image.height/dimension)*dimension,RGB)
result_dis = pdb.gimp_display_new(result_img)
result_layer = pdb.gimp_layer_new(result_img,result_img.width,result_img.height,RGBA_IMAGE,"result",100,NORMAL_MODE)
pdb.gimp_image_insert_layer(result_img,result_layer,None,0)
#set to use "clipboard" pattern
pdb.gimp_context_set_pattern(pdb.gimp_patterns_list('')[1][0])
#which_tile = 0
#pdb.gimp_display_delete(tile_compare_dis)
tile_index = 0
for y in range(0,int(image.height/dimension)): #image.height/dimension
for x in range(0,int(image.width/dimension)): #image.width/dimension
w_index = random.randrange(8) #pick a random orientation to use
#set variables to use that orientation
if w_index == 0:
tile_compare_img = tile_compare_img1
tile_layer = tile_layer1
elif w_index == 1:
tile_compare_img = tile_compare_img2
tile_layer = tile_layer2
elif w_index == 2:
tile_compare_img = tile_compare_img3
tile_layer = tile_layer3
elif w_index == 3:
tile_compare_img = tile_compare_img4
tile_layer = tile_layer4
elif w_index == 4:
tile_compare_img = tile_compare_img5
tile_layer = tile_layer5
elif w_index == 5:
tile_compare_img = tile_compare_img6
tile_layer = tile_layer6
elif w_index == 6:
tile_compare_img = tile_compare_img7
tile_layer = tile_layer7
elif w_index == 7:
tile_compare_img = tile_compare_img8
tile_layer = tile_layer8
#which_tile += 1 #increment which tile for next round
pdb.gimp_image_select_rectangle(image,CHANNEL_OP_REPLACE,x*dimension,y*dimension,dimension,dimension)
pdb.gimp_edit_copy(layer)
diff_layer = pdb.gimp_layer_new(tile_compare_img,tile_compare_img.width,tile_compare_img.height,RGBA_IMAGE,"difference",100,DIFFERENCE_MODE)
pdb.gimp_image_insert_layer(tile_compare_img,diff_layer,None,0)
pdb.gimp_drawable_fill(diff_layer,PATTERN_FILL)
comp_layer = pdb.gimp_layer_new_from_visible(tile_compare_img,tile_compare_img,"compute diff")
pdb.gimp_image_insert_layer(tile_compare_img,comp_layer,None,0)
pdb.gimp_selection_none(tile_compare_img)
#look through and compare and record lowest difference.sel
#best_difference = 3000
#best_x = 0
#best_y = 0
l = [[3000, 0, 0], [3000,0,0], [3000,0,0], [3000,0,0], [3000,0,0], [3000,0,0]]
#l = sorted(l, key=getKey)
for cy in range(0,int(tile_compare_img.height/dimension)):
for cx in range(0,int(tile_compare_img.width/dimension)):
num_channels,pixel = pdb.gimp_drawable_get_pixel(comp_layer,cx * dimension + 1,cy * dimension + 1)
difference = pixel[0]+pixel[1]+pixel[2]
l[5][0],l[5][1],l[5][2] = difference,cx,cy
l = sorted(l, key=getKey)
#if difference < best_difference: #if we find a better match, record best x and best y
#best_difference,best_x,best_y = difference,cx,cy
#copy best match tile from tile layer
#pdb.gimp_message(str(best_x) + "," + str(best_y))
pick_a_best = random.randrange(5)
best_x = l[pick_a_best][1]
best_y = l[pick_a_best][2]
pdb.gimp_image_select_rectangle(tile_compare_img,CHANNEL_OP_REPLACE,best_x*dimension,best_y*dimension,dimension,dimension)
pdb.gimp_edit_copy(tile_layer)
floating_sel = pdb.gimp_edit_paste(result_layer,True)
pdb.gimp_floating_sel_to_layer(floating_sel)
pdb.gimp_layer_set_offsets(floating_sel,x*dimension,y*dimension)
result_layer = pdb.gimp_image_merge_down(result_img,floating_sel,CLIP_TO_BOTTOM_LAYER)
#removed layers we worked with for the compare
pdb.gimp_image_remove_layer(tile_compare_img,comp_layer)
pdb.gimp_image_remove_layer(tile_compare_img,diff_layer)
pdb.gimp_displays_flush() #display as we finish one line
pdb.gimp_display_delete(tile_compare_dis1)
pdb.gimp_display_delete(tile_compare_dis2)
pdb.gimp_display_delete(tile_compare_dis3)
pdb.gimp_display_delete(tile_compare_dis4)
pdb.gimp_display_delete(tile_compare_dis5)
pdb.gimp_display_delete(tile_compare_dis6)
pdb.gimp_display_delete(tile_compare_dis7)
pdb.gimp_display_delete(tile_compare_dis8)
pdb.gimp_image_remove_layer(image,layer)
#UNCOMMENT BELOW WHEN DONE
pdb.gimp_context_pop()
pdb.gimp_image_undo_group_end(image)
pdb.gimp_displays_flush()
#return
register(
"python_fu_tt_tile_match",
"Tile match source image using Tile image of given tile dimension",
"Tile match source image using Tile image of given tile dimension",
"Tin Tran",
"Tin Tran",
"July 2017",
"<Image>/Python-Fu/Tile Match...", #Menu path
"RGB*, GRAY*",
[
(PF_IMAGE, "tile_image", "Tile Image:", None),
(PF_SPINNER, "dimension", "Tile Dimension(pixels):", 50, (10, 500, 1)),
#(PF_SPINNER, "blur_radius", "Guasian Blur Radius:", 33, (0, 12800, 0.1)), # alias PF_ADJUSTMENT
],
[],
python_tt_tile_match)
main()