GIMP python line drawing very slow

912 Views Asked by At

pdb.gimp_paintbrush_default seems to be very slow (several seconds, for 500 dots using a standard brush. Lines are worse, obviously). Is this the way it is? Is there a way to speed things up when drawing straight lines using the user selected brush?

pythonfu console code:

from random import randint
img=gimp.image_list()[0]
drw = pdb.gimp_image_active_drawable(img)

width = pdb.gimp_image_width(img)
height = pdb.gimp_image_height(img)

point_number = 500
while (point_number > 0):
  x = randint(0, width)
  y = randint(0, height)
  pdb.gimp_paintbrush_default(drw,2,[x,y])
  point_number -= 1
1

There are 1 best solutions below

2
On

I've been working on something very similar and ran into this problem also. Here's one technique that I found that made my function about 5 times faster:

  1. Create a temporary image
  2. Copy the layer you are working with to the temporary image
  3. Do the drawing on the temporary layer
  4. Copy the temporary layer on top of the original layer

I believe this speeds stuff up because GIMP doesn't have to draw the edits to the screen, but I'm not 100% sure. Here's my function:

def splotches(img, layer, size, variability, quantity):

    gimp.context_push()
    img.undo_group_start()

    width = layer.width
    height = layer.height

    temp_img = pdb.gimp_image_new(width, height, img.base_type)
    temp_img.disable_undo()

    temp_layer = pdb.gimp_layer_new_from_drawable(layer, temp_img)
    temp_img.insert_layer(temp_layer)

    brush = pdb.gimp_brush_new("Splotch")
    pdb.gimp_brush_set_hardness(brush, 1.0)
    pdb.gimp_brush_set_shape(brush, BRUSH_GENERATED_CIRCLE)
    pdb.gimp_brush_set_spacing(brush, 1000)
    pdb.gimp_context_set_brush(brush)

    for i in range(quantity):
        random_size = size + random.randrange(variability)

        x = random.randrange(width)
        y = random.randrange(height)

        pdb.gimp_context_set_brush_size(random_size)
        pdb.gimp_paintbrush(temp_layer, 0.0, 2, [x, y, x, y], PAINT_CONSTANT, 0.0)

        gimp.progress_update(float(i) / float(quantity))

    temp_layer.flush()
    temp_layer.merge_shadow(True)

    # Delete the original layer and copy the new layer in its place
    new_layer = pdb.gimp_layer_new_from_drawable(temp_layer, img)
    name = layer.name
    img.remove_layer(layer)
    pdb.gimp_item_set_name(new_layer, name)
    img.insert_layer(new_layer)

    gimp.delete(temp_img)

    img.undo_group_end()
    gimp.context_pop()