Re: [Gimp-developer] Optimizing border-like selection in python
On 27/09/2010 18:47, saulgo...@flashingtwelve.brickfilms.com wrote: Quoting Ofnutsofn...@laposte.net: My code needs to do a one-pixel-wide selection, at distance x from the current selection. This looks a lot like a border selection except that the border selection creates at best a two-pixel wide ribbon and I only want one (but if I'm wrong, please tell me how to :-) So far my code goes like this: # Selects pixels that are between x and x+1 pixels from # the original selection. Bumping the selection by one # each time doesn't work, a small circle degenerates into # a square with rounded corners instead of a big circle. def select_ribbon(self,image,selection,dist): pdb.gimp_selection_load(selection) pdb.gimp_selection_grow(image,dist+1) outer=pdb.gimp_selection_save(image) pdb.gimp_selection_load(selection) pdb.gimp_selection_grow(image,dist) inner=pdb.gimp_selection_save(image) pdb.gimp_channel_combine_masks(outer,inner,CHANNEL_OP_SUBTRACT,0,0) pdb.gimp_selection_load(outer) image.remove_channel(outer) image.remove_channel(inner) That works, but can be slow (especially since it's at the core of a loop). Is there any better way? Or useless code to jettison? There is no need to create (and later delete) the 'outer' channel. Just use the selection itself. In Script-fu, this would be done as follows: (gimp-selection-load selection) (gimp-selection-grow image dist) (set! inner (car (gimp-selection-save image))) (gimp-selection-load selection) (gimp-selection-grow image (+ dist 1)) (gimp-channel-combine-masks (car (gimp-image-get-selection image)) inner CHANNEL-OP-SUBTRACT 0 0) (gimp-image-remove-channel image inner) Implemented your code. It runs 10 to 20% faster, and uses only half the memory... So you have been duly credited in the V0.2 history. Thx. ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
Re: [Gimp-developer] Optimizing border-like selection in python
On 24/09/2010 17:05, Joao S. O. Bueno wrote: On Fri, Sep 24, 2010 at 11:19 AM, Ofnutsofn...@laposte.net wrote: Hi, My code needs to do a one-pixel-wide selection, at distance x from the current selection. This looks a lot like a border selection except that the border selection creates at best a two-pixel wide ribbon and I only want one (but if I'm wrong, please tell me how to :-) So far my code goes like this: # Selects pixels that are between x and x+1 pixels from # the original selection. Bumping the selection by one # each time doesn't work, a small circle degenerates into # a square with rounded corners instead of a big circle. def select_ribbon(self,image,selection,dist): pdb.gimp_selection_load(selection) pdb.gimp_selection_grow(image,dist+1) outer=pdb.gimp_selection_save(image) pdb.gimp_selection_load(selection) pdb.gimp_selection_grow(image,dist) inner=pdb.gimp_selection_save(image) pdb.gimp_channel_combine_masks(outer,inner,CHANNEL_OP_SUBTRACT,0,0) pdb.gimp_selection_load(outer) image.remove_channel(outer) image.remove_channel(inner) That works, but can be slow (especially since it's at the core of a loop). Is there any better way? Or useless code to jettison? Next improvement is to create a 3-pixels selection and feather it one pixel. Anything to be wary of? Hmm..this _will_ be slow. :-) You can speed it up by making a copy of your drawable to another image, disable the undo system on this new image and perform your cations above, before copying the results back to the original image - but it is about it. Maybe you can perform the whole loop in the copy with undo disabled - but I don't know your intent. Disabling undo on the main image (just for tests) doesn't show much speed gain (from 2'03 to 1'56 in my test). It's only better memory-wise. ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
Re: [Gimp-developer] Optimizing border-like selection in python
On Mon, Sep 27, 2010 at 3:45 AM, Ofnuts ofn...@laposte.net wrote: On 24/09/2010 17:05, Joao S. O. Bueno wrote: On Fri, Sep 24, 2010 at 11:19 AM, Ofnutsofn...@laposte.net wrote: Hi, My code needs to do a one-pixel-wide selection, at distance x from the current selection. This looks a lot like a border selection except that the border selection creates at best a two-pixel wide ribbon and I only want one (but if I'm wrong, please tell me how to :-) So far my code goes like this: # Selects pixels that are between x and x+1 pixels from # the original selection. Bumping the selection by one # each time doesn't work, a small circle degenerates into # a square with rounded corners instead of a big circle. def select_ribbon(self,image,selection,dist): pdb.gimp_selection_load(selection) pdb.gimp_selection_grow(image,dist+1) outer=pdb.gimp_selection_save(image) pdb.gimp_selection_load(selection) pdb.gimp_selection_grow(image,dist) inner=pdb.gimp_selection_save(image) pdb.gimp_channel_combine_masks(outer,inner,CHANNEL_OP_SUBTRACT,0,0) pdb.gimp_selection_load(outer) image.remove_channel(outer) image.remove_channel(inner) That works, but can be slow (especially since it's at the core of a loop). Is there any better way? Or useless code to jettison? Next improvement is to create a 3-pixels selection and feather it one pixel. Anything to be wary of? Hmm..this _will_ be slow. :-) You can speed it up by making a copy of your drawable to another image, disable the undo system on this new image and perform your cations above, before copying the results back to the original image - but it is about it. Maybe you can perform the whole loop in the copy with undo disabled - but I don't know your intent. Disabling undo on the main image (just for tests) doesn't show much speed gain (from 2'03 to 1'56 in my test). It's only better memory-wise. Hmm..maybe soem of the spped-up I experience has tod o with the new image I create on BG not being displayed - it will certainly help on this due to the marching ants that are used midway that don't need to show up. js -- ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
Re: [Gimp-developer] Optimizing border-like selection in python
On Mon, 2010-09-27 at 08:58 -0300, Joao S. O. Bueno wrote: Hmm..maybe soem of the spped-up I experience has tod o with the new image I create on BG not being displayed - it will certainly help on this due to the marching ants that are used midway that don't need to show up. Shouldn't make much of a difference. The change to the selection only invalidates the view and queues a redraw. The pending redraw shouldn't slow things down considerably. Sven ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
[Gimp-developer] Optimizing border-like selection in python
Hi, My code needs to do a one-pixel-wide selection, at distance x from the current selection. This looks a lot like a border selection except that the border selection creates at best a two-pixel wide ribbon and I only want one (but if I'm wrong, please tell me how to :-) So far my code goes like this: # Selects pixels that are between x and x+1 pixels from # the original selection. Bumping the selection by one # each time doesn't work, a small circle degenerates into # a square with rounded corners instead of a big circle. def select_ribbon(self,image,selection,dist): pdb.gimp_selection_load(selection) pdb.gimp_selection_grow(image,dist+1) outer=pdb.gimp_selection_save(image) pdb.gimp_selection_load(selection) pdb.gimp_selection_grow(image,dist) inner=pdb.gimp_selection_save(image) pdb.gimp_channel_combine_masks(outer,inner,CHANNEL_OP_SUBTRACT,0,0) pdb.gimp_selection_load(outer) image.remove_channel(outer) image.remove_channel(inner) That works, but can be slow (especially since it's at the core of a loop). Is there any better way? Or useless code to jettison? Next improvement is to create a 3-pixels selection and feather it one pixel. Anything to be wary of? -- Ofnuts ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
Re: [Gimp-developer] Optimizing border-like selection in python
On Fri, Sep 24, 2010 at 11:19 AM, Ofnuts ofn...@laposte.net wrote: Hi, My code needs to do a one-pixel-wide selection, at distance x from the current selection. This looks a lot like a border selection except that the border selection creates at best a two-pixel wide ribbon and I only want one (but if I'm wrong, please tell me how to :-) So far my code goes like this: # Selects pixels that are between x and x+1 pixels from # the original selection. Bumping the selection by one # each time doesn't work, a small circle degenerates into # a square with rounded corners instead of a big circle. def select_ribbon(self,image,selection,dist): pdb.gimp_selection_load(selection) pdb.gimp_selection_grow(image,dist+1) outer=pdb.gimp_selection_save(image) pdb.gimp_selection_load(selection) pdb.gimp_selection_grow(image,dist) inner=pdb.gimp_selection_save(image) pdb.gimp_channel_combine_masks(outer,inner,CHANNEL_OP_SUBTRACT,0,0) pdb.gimp_selection_load(outer) image.remove_channel(outer) image.remove_channel(inner) That works, but can be slow (especially since it's at the core of a loop). Is there any better way? Or useless code to jettison? Next improvement is to create a 3-pixels selection and feather it one pixel. Anything to be wary of? Hmm..this _will_ be slow. :-) You can speed it up by making a copy of your drawable to another image, disable the undo system on this new image and perform your cations above, before copying the results back to the original image - but it is about it. Maybe you can perform the whole loop in the copy with undo disabled - but I don't know your intent. js -- -- Ofnuts ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
Re: [Gimp-developer] Optimizing border-like selection in python
On 24/09/2010 19:44, Ofnuts wrote: The whole plugin paints successive concentric uniform 1-pixel ribbons around the original selection (pixel values a obtained from another layer). On my laptop (T2400, 1.83GHz) it takes roughly 10 seconds to draw 20 concentric ribbons around a 500-pixels circular selection. The whole thing runs within a undo_group_start()/image.undo_group_end() so I don't expect any more undos? By the way, when my plug-in runs, the marching ants go into a frenzy, as if each selection change caused a screen update (though the bucket-fills don't show until the whole thing is finished). Would disabling these updates speed things up? (if so how is it done?) -- Ofnuts ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
Re: [Gimp-developer] Optimizing border-like selection in python
You can't disable the border selection programatically. In such cases what I've done is duplicate the image without displaying it and perform all the selection work on the duplicate then copy and paste it in as a channel into the original image. Then channel to Selection and delete the channel. -Rob A On 9/24/10, Ofnuts ofn...@laposte.net wrote: On 24/09/2010 19:44, Ofnuts wrote: The whole plugin paints successive concentric uniform 1-pixel ribbons around the original selection (pixel values a obtained from another layer). On my laptop (T2400, 1.83GHz) it takes roughly 10 seconds to draw 20 concentric ribbons around a 500-pixels circular selection. The whole thing runs within a undo_group_start()/image.undo_group_end() so I don't expect any more undos? By the way, when my plug-in runs, the marching ants go into a frenzy, as if each selection change caused a screen update (though the bucket-fills don't show until the whole thing is finished). Would disabling these updates speed things up? (if so how is it done?) -- Ofnuts ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
Re: [Gimp-developer] Optimizing border-like selection in python
Calculating a new selection from the current selection would be faster (I think): def create_border(image, selection_type='rectangle', size=1): is_selection, x1, y1, x2, y2 = pdb.gimp_selection_bounds(image) if is_selection: if size 1: size = 1 if selection_type =='rectangle': pdb.gimp_rect_select(image, x1+size, y1+size, (x2-x1)-(size*2), (y2-y1)-(size*2), CHANNEL_OP_SUBTRACT, False, 0) elif selection_type == 'ellipse': pdb.gimp_ellipse_select(image, x1+size, y1+size, (x2-x1)-(size*2), (y2-y1)-(size*2), CHANNEL_OP_SUBTRACT, True, False, 0) else: gimp.message(Please make a selection...) def test_plugin(image, drawable): image.undo_group_start() create_border(image)# A rectangular selecion with default settings... #create_border(image, selection_type='ellipse', size=3) # Or Ellipse with custom settings... # Fill pdb.gimp_edit_fill(drawable, 0) pdb.gimp_selection_none(image) image.undo_group_end() On 09/24/2010 10:19 AM, Ofnuts wrote: Hi, My code needs to do a one-pixel-wide selection, at distance x from the current selection. This looks a lot like a border selection except that the border selection creates at best a two-pixel wide ribbon and I only want one (but if I'm wrong, please tell me how to :-) So far my code goes like this: # Selects pixels that are between x and x+1 pixels from # the original selection. Bumping the selection by one # each time doesn't work, a small circle degenerates into # a square with rounded corners instead of a big circle. def select_ribbon(self,image,selection,dist): pdb.gimp_selection_load(selection) pdb.gimp_selection_grow(image,dist+1) outer=pdb.gimp_selection_save(image) pdb.gimp_selection_load(selection) pdb.gimp_selection_grow(image,dist) inner=pdb.gimp_selection_save(image) pdb.gimp_channel_combine_masks(outer,inner,CHANNEL_OP_SUBTRACT,0,0) pdb.gimp_selection_load(outer) image.remove_channel(outer) image.remove_channel(inner) That works, but can be slow (especially since it's at the core of a loop). Is there any better way? Or useless code to jettison? Next improvement is to create a 3-pixels selection and feather it one pixel. Anything to be wary of? -- Ofnuts ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
Re: [Gimp-developer] Optimizing border-like selection in python
Ahh... autoformatting... this should be easier to read... (sorry) def create_border(image, selection_type='rectangle', size=1): is_selection, x1, y1, x2, y2 = pdb.gimp_selection_bounds(image) if is_selection: if size 1: size = 1 if selection_type =='rectangle': pdb.gimp_rect_select(image, x1+size, y1+size, (x2-x1)-(size*2), (y2-y1)-(size*2), CHANNEL_OP_SUBTRACT, False, 0) elif selection_type == 'ellipse': pdb.gimp_ellipse_select(image, x1+size, y1+size, (x2-x1)-(size*2), (y2-y1)-(size*2), CHANNEL_OP_SUBTRACT, True, False, 0) else: gimp.message(Please make a selection...) def test_plugin(image, drawable): image.undo_group_start() # A rectangular selecion with default settings... create_border(image) # Ellipse with custom settings... Uncomment to activate #create_border(image, selection_type='ellipse', size=3) # Fill pdb.gimp_edit_fill(drawable, 0) pdb.gimp_selection_none(image) image.undo_group_end() On 09/24/2010 06:18 PM, Jerry Baker wrote: Calculating a new selection from the current selection would be faster (I think): def create_border(image, selection_type='rectangle', size=1): is_selection, x1, y1, x2, y2 = pdb.gimp_selection_bounds(image) if is_selection: if size 1: size = 1 if selection_type =='rectangle': pdb.gimp_rect_select(image, x1+size, y1+size, (x2-x1)-(size*2), (y2-y1)-(size*2), CHANNEL_OP_SUBTRACT, False, 0) elif selection_type == 'ellipse': pdb.gimp_ellipse_select(image, x1+size, y1+size, (x2-x1)-(size*2), (y2-y1)-(size*2), CHANNEL_OP_SUBTRACT, True, False, 0) else: gimp.message(Please make a selection...) def test_plugin(image, drawable): image.undo_group_start() create_border(image)# A rectangular selecion with default settings... #create_border(image, selection_type='ellipse', size=3) # Or Ellipse with custom settings... # Fill pdb.gimp_edit_fill(drawable, 0) pdb.gimp_selection_none(image) image.undo_group_end() On 09/24/2010 10:19 AM, Ofnuts wrote: Hi, My code needs to do a one-pixel-wide selection, at distance x from the current selection. This looks a lot like a border selection except that the border selection creates at best a two-pixel wide ribbon and I only want one (but if I'm wrong, please tell me how to :-) So far my code goes like this: # Selects pixels that are between x and x+1 pixels from # the original selection. Bumping the selection by one # each time doesn't work, a small circle degenerates into # a square with rounded corners instead of a big circle. def select_ribbon(self,image,selection,dist): pdb.gimp_selection_load(selection) pdb.gimp_selection_grow(image,dist+1) outer=pdb.gimp_selection_save(image) pdb.gimp_selection_load(selection) pdb.gimp_selection_grow(image,dist) inner=pdb.gimp_selection_save(image) pdb.gimp_channel_combine_masks(outer,inner,CHANNEL_OP_SUBTRACT,0,0) pdb.gimp_selection_load(outer) image.remove_channel(outer) image.remove_channel(inner) That works, but can be slow (especially since it's at the core of a loop). Is there any better way? Or useless code to jettison? Next improvement is to create a 3-pixels selection and feather it one pixel. Anything to be wary of? -- Ofnuts ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
Re: [Gimp-developer] Optimizing border-like selection in python
The code should work for any shape of selection (for instance after a text-to-selection). Actually the plugin this routine is part of hasn't got much merit on rectangular/circular selections... On 25/09/2010 00:27, Jerry Baker wrote: Ahh... autoformatting... this should be easier to read... (sorry) def create_border(image, selection_type='rectangle', size=1): is_selection, x1, y1, x2, y2 = pdb.gimp_selection_bounds(image) if is_selection: if size 1: size = 1 if selection_type =='rectangle': pdb.gimp_rect_select(image, x1+size, y1+size, (x2-x1)-(size*2), (y2-y1)-(size*2), CHANNEL_OP_SUBTRACT, False, 0) elif selection_type == 'ellipse': pdb.gimp_ellipse_select(image, x1+size, y1+size, (x2-x1)-(size*2), (y2-y1)-(size*2), CHANNEL_OP_SUBTRACT, True, False, 0) else: gimp.message(Please make a selection...) def test_plugin(image, drawable): image.undo_group_start() # A rectangular selecion with default settings... create_border(image) # Ellipse with custom settings... Uncomment to activate #create_border(image, selection_type='ellipse', size=3) # Fill pdb.gimp_edit_fill(drawable, 0) pdb.gimp_selection_none(image) image.undo_group_end() On 09/24/2010 06:18 PM, Jerry Baker wrote: Calculating a new selection from the current selection would be faster (I think): def create_border(image, selection_type='rectangle', size=1): is_selection, x1, y1, x2, y2 = pdb.gimp_selection_bounds(image) if is_selection: if size 1: size = 1 if selection_type =='rectangle': pdb.gimp_rect_select(image, x1+size, y1+size, (x2-x1)-(size*2), (y2-y1)-(size*2), CHANNEL_OP_SUBTRACT, False, 0) elif selection_type == 'ellipse': pdb.gimp_ellipse_select(image, x1+size, y1+size, (x2-x1)-(size*2), (y2-y1)-(size*2), CHANNEL_OP_SUBTRACT, True, False, 0) else: gimp.message(Please make a selection...) def test_plugin(image, drawable): image.undo_group_start() create_border(image) # A rectangular selecion with default settings... #create_border(image, selection_type='ellipse', size=3) # Or Ellipse with custom settings... # Fill pdb.gimp_edit_fill(drawable, 0) pdb.gimp_selection_none(image) image.undo_group_end() ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer