2

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
mikro
  • 125
  • 7

1 Answers1

2

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()
Stephen
  • 21
  • 4
  • Thanks, I've written a small benchmark using your method but I'm getting non-conclusive results of any kind; sometimes slower, sometimes faster. If you want to take a look, it is here [link](http://www.mikropunto.org/wp-content/uploads/paintbrush_default_benchmark.tar.gz) – mikro Mar 09 '16 at 22:25
  • 2
    I think that things might be different if you make one call to gimp_paintbrush_default with a bunch of points vs making a few hundred calls to it with a single point. Another thing that might be speeding up the function in my code is the "temp_img.disable_undo()" call. If GIMP doesn't have to record any undo information it might speed things up. That probably wouldn't affect one big call to gimp_paintbrush_default though. – Stephen Mar 12 '16 at 15:55