# [Gimp-developer] python plugin

```Hello everybody,
my name is Emanuele Zattin and i'm developing a plug-in implementing a
texture synthesis algorithm described in a paper ("Texture Synthesis
by Non-parametric sampling" by Efros and Leung).
Here attached you can  see my actual implementation which works on
grayscale images. It is anyway VERY slow, which was anyway predictable
judging from the complexity of the algorithm.
I was wondering if translating it to C would make it much faster or if
there are some more speedup techniques i'm just missing.```
```
Thank you very much!!

Emanuele Zattin
```
```#!/usr/bin/python

import math
from gimpfu import *
from Numeric import *

def getpixel(drawable, x, y):
tile = drawable.get_tile2(FALSE, x, y)
x_offset = x % 64
y_offset = y % 64
pixel = tile[x_offset, y_offset]

values = []
for i in range(len(pixel)):
values.append(ord(pixel[i]))

if len(values) == 1:
values.append(255)

return values

def putpixel(drawable, x, y, value):
tile = drawable.get_tile2(FALSE, x, y)
x_offset = x % 64
y_offset = y % 64
tile[x_offset, y_offset] = chr(value) + chr(255)

return

def texture_synthesis(image, drawable, w):
# first let's retrieve some useful stats about the current layer
layer = image.active_layer
height = layer.height
width = layer.width

gimp.tile_cache_ntiles(2 * (width + 63) / 64)

# where are the transparent pixels?
gimp.progress_init("Gathering stats...")
transparent = []
for i in range(width):
for j in range(height):
pixel = getpixel(layer, i, j)
if pixel[1] < 255:
transparent.append([i, j])
gimp.progress_update(float(i-w)/(width-1-2*w))

if len(transparent) == 0:
return

while len(transparent) > 0:

# which is the next pixel to synthetize?
neighbours = []
for index in range(len(transparent)):
count = 0
pixel_pos = transparent[index]
for x in range(max(0, pixel_pos[0]-w), min(width, pixel_pos[0]+w)):
for y in range(max(0, pixel_pos[1]-w), min(height, pixel_pos[1]+w)):
pixel = getpixel(layer, x, y)
if pixel[1] == 255:
count = count + 1
neighbours.append(count)

trans_index = neighbours.index(max(neighbours))

next_pixel_pos = transparent[trans_index]

# create the pattern around that pixel
pattern = arrayrange((4*w*w+4*w+1))
pattern.shape = (2*w+1, 2*w+1)

for i in range(2*w+1):
for j in range(2*w+1):
# where's the pixel we're gonna check?
px = next_pixel_pos[0]+i-w
py = next_pixel_pos[1]+j-w

# is it in the image?
if px<0 or px>=width or py<0 or py>=height:
pixel = [-1, 0]
else:
pixel = getpixel(layer, px, py)

if pixel[1] == 255:
pattern[i,j] = pixel[0]
else:
if pixel[0] == -1:
pattern[i,j] = -1
else:
pattern[i,j] = 0

# let's find the closest matches
max_result = 0
values = []
positions = []
gimp.progress_init("Computing pixel: " + str(len(transparent)) + " more to go")
for i in range(width):
for j in range(height):
result = 0
dist = pow((next_pixel_pos[0]-i),2) + pow((next_pixel_pos[1]-j),2)
if dist > 0:
for x in range(2*w+1):
for y in range(2*w+1):
px = i+x-w
py = j+y-w
if px>=0 and px<width and py>=0 and py<height:
pixel = getpixel(layer, px, py)
if pixel[1] == 255 and pattern[x,y] >=0:
result = result + 255-abs(pixel[0]-pattern[x, y])

if result > max_result:
print "Matching: " + str(float(result)/(255*((2*w+1)*(2*w+1)))) +" ("+ str(i) +","+ str(j) + ")"
max_result = result
pixel = getpixel(layer, i, j)
values = []
values.append(pixel[0])
positions = []
positions.append([i, j])
elif result == max_result:
pixel = getpixel(layer, i, j)
values.append(pixel[0])
positions.append([i, j])

gimp.progress_update(float(i)/(width-1))

distances = []
for i in positions:
distances.append(pow((next_pixel_pos[0]-i[0]),2) + pow((next_pixel_pos[1]-i[1]),2))

min_distance_index = distances.index(min(distances))
min_distance_value = values[min_distance_index]

putpixel(layer, next_pixel_pos[0], next_pixel_pos[1], min_distance_value)
layer.update(next_pixel_pos[0], next_pixel_pos[1], 1, 1)

transparent[trans_index:trans_index+1] = []

register(
"TextureSynthesis",
"Synthetize transparent pixels of the current layer",
"Synthetize transparent pixels of the current layer",
"Ling Xu, Emanuele Zattin",
"Ling Xu, Emanuele Zattin",
"2006",
"<Image>/Python-Fu/Texture/Synthesis",
"GRAY*",
[
(PF_INT, "w", "Window Size", 9)
],
[],
texture_synthesis)

main()

```
```_______________________________________________
Gimp-developer mailing list
Gimp-developer@lists.XCF.Berkeley.EDU
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
```