Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Faking an undo step for functions that aren't undoable in Gimp
#1
I intended to make this a question, but I figured out a few ways to do it, so I'm posting in case someone ever comes across this and only finds some very old unanswered questions online.

Some low level Python methods for Gimp, like get_pixel_rgn() are not undoable. For exampe, if I create a small 24 bit image, I can make the first row red, by typing this in the Python console, but then it  can't be undone:

Code:
GIMP 2.6.12 Python Console
Python 2.7.18 (default, Jan 31 2024, 16:23:13)
[GCC 9.4.0]
➤> layer = gimp.image_list()[0].layers[0] # Newly created image.
➤> r = layer.get_pixel_rgn(0, layer.width, 0, 1) # First row.
➤> r[0:layer.width,0] = '\xff\x00\x00'*layer.width # Fill with red.
➤> layer.update(0, 0, layer.width, 1)
➤>
I wrote a plugin that is notably faster using this (obsolete) function, but I want to publish it and it's embarrassing that it can't be undone. So I need to simulate that an undo step was pushed into the stack:
Code:
image.undo_group_start() #Make the plugin's name appear in the undo history dialog.
pdb.gimp_brightness_contrast(drawable, 0, 0) # This does nothing, but a full image is stored.
image.undo_group_end() # Doesn't matter if the plugin has even started.


Some other things I've tried:


Creating a selection and deselecting it. Adds an undo state, but doesn't modify the image at all, so the changes to the image remain when trying to undo.

Copying and pasting the whole layer into itself. It works, but a very discocerting pop up of  "Copied pixels to the clipboard" could appear if there is not an error console open.

Duplicating the layer and merging it down. This always adds an alpha channel, the original layer might not have one.

I guess I'll use the dummy "brightness" tool or something similar unless someone already has or can come up with  a more elegant answer.
Reply
#2
Gimp 2.6.12? If you want to publish your thing you have better check that it still works with 2.10, and perhaps that there isno equivalent in 2.10 already, because things have improved significantly over the last 12 years.

Otherwise I can confirm the non-undoability of the pixel regions operations, but doing a set_pixel(get_pixel()) could be a bit more efficient than calling a GEGL operation over the whole layer...).
Reply
#3
Of course I've tested it with Gimp 2.10. Forward compatibility hasn't been an issue. Even complied plugins written in C work across  versions, I'm only using Linux though. Gimp 3 will surely break everything, but that's expected.

set_pixel() wouldn't work (edit: I mean as storage) as it also isn't an undoable operation, it even says so in the description.

Thanks Big Grin .
Reply


Forum Jump: