Post Reply 

Troubles duplicating a layer in a python script

Jan 6, 2012, 23:41
Post: #1
Troubles duplicating a layer in a python script
Hello, I have about 1000 .PNGs i need to process. I've been struggling for days. Gimp and Python are now working nicely. I'm writing a script to do the following. 1.invert the image, 2.blur the image, 3.copy the layer, 4.change blend to multiply, 5.copy layer two more times (also multiply mode), 6. merge visible, 7.resize image.

Eventually I would like to batch this.

As it stands I'm up to number 3. copy the layer

def WireProc(image, drawable) :

pdb.gimp_invert(drawable)
pdb.plug_in_gauss(image, drawable, 3, 3, 0)
pdb.gimp_layer_copy(drawable, TRUE)
pdb.gimp_image_add_layer(image, drawable, -1)


.txt  WireProc.txt (Size: 674 bytes / Downloads: 99)

Then I get an error

"Calling error for procedure 'gimp-image-add-layer':
Item 'Background' (2) has already been added to an image "

Sometimes the number in parenthesis is different. Ive tried many things.

Help would be greatly appreciated.
Find all posts by this user
Quote this message in a reply
Jan 7, 2012, 01:36
Post: #2
RE: Troubles duplicating a layer in a python script
No idea... but since you are in python, you can/should use the Python interface fully:
Code:
new_layer=image.add_layer(layer.copy(true),-1)
new_layer.name='whatever'
You can easily list all the layers in a an image:
Code:
print image.layers
or list if the layer is already in an image
Code:
print layer.image
You can get and set the layer mode
Code:
layer.mode=MULTIPLY_MODE
The doc at http://www.gimp.org/docs/python/index.html is a good start, and using dir() on some objects will show you some more methods (not all the code has bee documented, but they work and parameters are easy to guess). Constants such as MULTIPLY_MODE are defined in the gimpfu module, but since it is usually imported as "from gimpfu import *" you can't do a dir() on it, you have to "import gimpfu" for that.

Now answering your questions on
https://Gimp-Forum.net
Visit this user's website Find all posts by this user
Quote this message in a reply
Jan 7, 2012, 02:51
Post: #3
RE: Troubles duplicating a layer in a python script
ofnuts, Thanks for the quick reply. I'll keep at it. I thought that it would be best to keep from defining variables and just work on the currently active object. I'm also still figuring out the best workflow for testing code.

I just want to say that how much I appreciate the time you spend helping others learn. I've already read many of your posts. You and others like you are truly spreading the good one post at a time. Thank you.
Find all posts by this user
Quote this message in a reply
Jan 7, 2012, 10:38
Post: #4
RE: Troubles duplicating a layer in a python script
(Jan 7, 2012 02:51)cavedog Wrote:  ofnuts, Thanks for the quick reply. I'll keep at it. I thought that it would be best to keep from defining variables and just work on the currently active object. I'm also still figuring out the best workflow for testing code.
Having things in variables makes it easy to add debug instructions. Btw, I made a last minute change to the code above and it's obviously wrong. It should have been
Code:
new_layer=layer.copy(true)
new_layer.name='whatever'
image.add_layer(new_layer,-1)
To test/debug I resort to the good ol' print instructions. On Linux the output shows in a terminal session if you started Gimp from one. On Windows you may have to run gimp-console. To checlk for syntax errors, you can also just run your code outside of Gimp ("python your_scipt.py"). It will fail on the gimp-specific imports but if it goes that far the syntax is OK.

(Jan 7, 2012 02:51)cavedog Wrote:  I just want to say that how much I appreciate the time you spend helping others learn. I've already read many of your posts. You and others like you are truly spreading the good one post at a time. Thank you.
Every answer I make also adds to my own knowledge. I'm the one learning Gimp here Smile

Now answering your questions on
https://Gimp-Forum.net
Visit this user's website Find all posts by this user
Quote this message in a reply
Jan 7, 2012, 17:09
Post: #5
RE: Troubles duplicating a layer in a python script
Ofnuts,
I worked late into the night and, thanks to you, I got to the next step. I was able to get through the cleverly placed errors in your code. I'm sure you were just keeping me honest. I wouldn't want the code handed to me. It felt great to work it out.
I've read through some more of your posts. I'm working in the python console one line at a time. In order to get feedback. I'll have to try running from the terminal with the gimp console as you suggest. I have found the Windows command port a bit tricky. Most tutorials are written from the Linux perspective, so It adds yet one more level to the confusion. Though I've been able to slowly muddled through it.
It's very slow going, but you've got me on the right track.

Thanks Again
Find all posts by this user
Quote this message in a reply
Jan 7, 2012, 17:55
Post: #6
RE: Troubles duplicating a layer in a python script
Mistakes where not intentional... in other venues I don't post code, because it smells too much like doing someone's school assignment. But so far this isn't the case here (but CS teachers would be well inspired to ask for Gimp scripts instead of the usual unimaginative Python calculator). In this case I did a couple of changes on the fly and didn't check the result.

Running things in batch in Windows is indeed a bit more complicated than it is on Linux, but that doesn't mean that the Linux side of things is simple, especially with Python. If you want to batch you could be well inspired to write a Python plugin that you start from the Gimp UI, that loads files, processes and saves them in the background (you don't need an UI for this processing, you just need enough UI to access the plugin). The great advantage of Python over Scheme is that you keep an access to plenty of useful functionality that was not meant to be used inside Gimp.

Now answering your questions on
https://Gimp-Forum.net
Visit this user's website Find all posts by this user
Quote this message in a reply
Jan 8, 2012, 01:06
Post: #7
RE: Troubles duplicating a layer in a python script
Alright,
I'm back with a working script that does all the steps enumerated in my first post (minus one layer copy not needed). It wasn't pretty, it took way too long, but hey, I've learned a lot.

I thought I would explain my process and hopefully get some feedback on some of the issues I ran into.

Firstly, to make sure that everyone is on the same page, I'm working in GIMP 2.6.11 and Python 2.6.4 (This is what a particular tutorial suggested. I'm sure this could be a whole thread on its own.) and three python companions that all the tutorials I've seen suggest. Anyway, it works.

My workflow was this: I have one xxx.py file registered so that it shows up in the GIMP menu. Then another file xxxtest.py These are opened from the IDLE Python GUI. Then inside the GIMP python-fu console I cut and paste from test.py to the Python-fu console small bits at a time. If it works, I paste it into the final xxx.py that is accessed through the menu and test it there (If it works in the Python-fu then it always works in the script).

A couple of issues that my newbness ran into:

In the python-fu console some of the code that I saw in tutorials and some that ofnuts so kindly showed me wouldn't work. For instance :

new_layer=layer.copy(true)
new_layer.name='whatever'
image.add_layer(new_layer,-1)

errors like: AttributeError: 'NoneType' object has no attribute 'name'

I ended up solving this by using the PDB (python database browser). and wrote this:

new_layer=image.add_layer(pdb.gimp_layer_copy(layer, True),-1)
layer=image.active_layer
pdb.gimp_drawable_set_name(layer, 'copy1')

This code worked in both the python-fu console and the xxx.py script.
I later surmised that if I used the "not working" code in my finished script it would work. Later I went back to my script and got rid of as much of the pdb. stuff I could.
I"m sure that I was supposed to import something while working in the Python-fu console.

Also Python would not take true or TRUE as an argument. Only True would work. That's an hour I'll never get back.

I'll leave it at that for now. The final script is at the bottom of this post.

Next is to figure out how to batch process.

Thanks again to ofnuts.

BTW this script is to process some wire frame renders that will be composited over a shaded model. the wire is dancing all over the place. They are way too pixelated. This makes them acceptable. It's a must. GIMP to the rescue.


Attached File(s)
.txt  WireProc.py.txt (Size: 968 bytes / Downloads: 92)
Find all posts by this user
Quote this message in a reply
Jan 8, 2012, 02:17
Post: #8
RE: Troubles duplicating a layer in a python script
(Jan 8, 2012 01:06)cavedog Wrote:  Alright,
I'm back with a working script that does all the steps enumerated in my first post (minus one layer copy not needed). It wasn't pretty, it took way too long, but hey, I've learned a lot.

I thought I would explain my process and hopefully get some feedback on some of the issues I ran into.

Firstly, to make sure that everyone is on the same page, I'm working in GIMP 2.6.11 and Python 2.6.4 (This is what a particular tutorial suggested. I'm sure this could be a whole thread on its own.) and three python companions that all the tutorials I've seen suggest. Anyway, it works.

My workflow was this: I have one xxx.py file registered so that it shows up in the GIMP menu. Then another file xxxtest.py These are opened from the IDLE Python GUI. Then inside the GIMP python-fu console I cut and paste from test.py to the Python-fu console small bits at a time. If it works, I paste it into the final xxx.py that is accessed through the menu and test it there (If it works in the Python-fu then it always works in the script).

A couple of issues that my newbness ran into:

In the python-fu console some of the code that I saw in tutorials and some that ofnuts so kindly showed me wouldn't work. For instance :

new_layer=layer.copy(true)
new_layer.name='whatever'
image.add_layer(new_layer,-1)

errors like: AttributeError: 'NoneType' object has no attribute 'name'

I ended up solving this by using the PDB (python database browser). and wrote this:

new_layer=image.add_layer(pdb.gimp_layer_copy(layer, True),-1)
layer=image.active_layer
pdb.gimp_drawable_set_name(layer, 'copy1')
You are throwing the baby with the bath water. OK, there were a couple of syntax errors, but that doesn't mean the code is completely invalid. You don't need the clunky PDB syntax for that:
Code:
>>># In you script you would get image/layer as plugin parameters
>>> image=gimp.image_list()[0]
>>> layer=image.layers[0]
>>> new_layer=layer.copy(true)
>>> new_layer=layer.copy(True)
>>> print new_layer
<gimp.Layer 'Background copy'>
>>> new_layer.name='name of copy'
>>> image.add_layer(new_layer,-1)
>>> print image.layers
[<gimp.Layer 'name of copy'>, <gimp.Layer 'Background'>]

(Jan 8, 2012 01:06)cavedog Wrote:  This code worked in both the python-fu console and the xxx.py script.
I later surmised that if I used the "not working" code in my finished script it would work. Later I went back to my script and got rid of as much of the pdb. stuff I could.
I"m sure that I was supposed to import something while working in the Python-fu console.

Also Python would not take true or TRUE as an argument. Only True would work. That's an hour I'll never get back.
Googling for Python booleans would have saved you one hour. And I thought IDLE did syntax highlighting, so you should have noticed that "true" did display like a variable.
(Jan 8, 2012 01:06)cavedog Wrote:  I'll leave it at that for now. The final script is at the bottom of this post.

Next is to figure out how to batch process.
As I said before, it will be easier to start the batch from inside Gimp by writing a plugin that will do the processing instead of a "Gimp batch". But if you want to use a gimp batch I have attached a sample I did a while ago.

(Jan 8, 2012 01:06)cavedog Wrote:  BTW this script is to process some wire frame renders that will be composited over a shaded model. the wire is dancing all over the place. They are way too pixelated. This makes them acceptable. It's a must. GIMP to the rescue.
If you can get your wireframe as numbers (X/Y coordinates), you can get the wireframe rendered in Gimp a lot more properly. I have a script that will import "Paths" from CSV. The path can they be stroked in Gimp and this would give perfect results directly. For instance this picture has been computed in an OpenOffice spreadsheet and imported as a path. The path has then been transformed into a selection and filled.

[attachment=837]

If you want to have a shot at it, see https://sourceforge.net/projects/gimp-path-tools/ and check the path-csv script.

Now answering your questions on
https://Gimp-Forum.net
Visit this user's website Find all posts by this user
Quote this message in a reply
Jan 8, 2012, 17:34
Post: #9
RE: Troubles duplicating a layer in a python script
Ofnuts,
I have come here for help and you are kind enough to give it. I'm afraid my ignorance is showing through. This is, for the most part,my first effort at programming. I'm winging it. In my last post I wanted to share my confusion. I could just ask a question and never come back but I thought it was proper to update my process for anyone interested. Ideally I would take some courses and learn things properly. I don't have that luxury. I have a problem I need to solve. And as unknowledgeable as I am, thanks to you and the vast jumble of resources on the internet, I'm getting it done and learning important skills.

I'm still clueless about why the code worked in the script but not in the Python-fu console. I'll figure it out. From my perspective (confused and over my head) you just keep trying things, Google some more, and try some more things. Using the PDB code worked. I knew from your earlier post that it was less than ideal, but it worked. At 2:00 am, after a day of toil, I found a way. In the end I knew I would try to use better code. Which I did. And of course the "True" issue shouldn't have happened. It simply demonstrates my confusion, which was my intent.

About my finished script. It works but is it correct? One thing I noticed is that there is no need to name the layers since they are merged later. Originally when I was having trouble duplicating the layer I though it might be needed in order to copy the layer. Its not. Also I'm sure I ran into image.scale command somewhere.

Also, does the workflow I'm using make sense?

And then, as far as processing the files, I need to get my nomenclature right. You don't "batch" from within GIMP, noted. I will follow your advise and process from within GIMP if I can. I've collected a lot of examples of batch processing from the command line. I'll Google it.

Lastly, Ofnuts, your "Paths" from CSV looks fantastic. Does Blender have an appropriate export type? Too late for this time. The 1000 or so frames took a week to render. I have to say my fix, though not ideal, does the job well.

In conclusion Ofnuts, I hope in the future I can to discuss Python on a higher level. Until then, if you'll have me, I'm sure I will I will test your patience some more. What your doing here borders on the saintly. Thank you again.
Find all posts by this user
Quote this message in a reply
Jan 8, 2012, 21:15
Post: #10
RE: Troubles duplicating a layer in a python script
Attached, a zip with:
  • a duly commented Wireproc.py showing your bugs (yes, there are some) and various code enhancements that make the whole thing easier to read/enhance/fix
  • a cleaned-up version. Notice how the common layer duplication code has been moved to its own function. Also added the two instructions to make the whole script undoable with a single Ctrl-Z.
If this is your first foray into Python you are doing well. If this is you first into programming you are doing extremely well.

As to your questions:

in the python console, you may have had uninitialized variables. Don't lose sleep over that.

You code isn't completely correct, see files above. No code is ever 100% correct, mind. But 98% correctness is much better than 40%. The mere fact that you make the distinction between code that produces the expected results and correct code is fairly encouraging about your ability to produce correct code someday. There are <cough>professional programmers</cough> who have not found that out yet.

3) image.scale() is one of these undocumented things I alluded to. In python you can use dir(object) to see what methods/attributes can be used against an object. Guessing the parameters is not too hard (usually fairly close to the PDB equivalents)

3) yes your procedure makes sense. You taught me something there... thx.

4) for path-csv, I don't know what Blender can export. There is the data and there is the format. The data is important but the format can be changed. To keep my script simple I support only the CSV format, which is fairly universal and can be produced directly from spreadsheets. You may have to write a python script to convert the output from Blender into CSV. PM me if you need help for this.

Now answering your questions on
https://Gimp-Forum.net
Visit this user's website Find all posts by this user
Quote this message in a reply
Jan 9, 2012, 07:04
Post: #11
RE: Troubles duplicating a layer in a python script
Ofnuts, Ofnuts, Ofnuts,

You've lifted the veil off the code for me to see. So generous of you! And your cleaned up version is PURE POETRY! Concise and modular. I'm sure I can't fully comprehend how great it is. Professional.

I will spend some time studying this. And hopefully tomorrow I will decipher this globbing thing.

BTW full disclosure. I did some Basic in a high school computer course(1984), I pasted together a mel script and I've done some Flash Action scripting tutorials. But honestly most of this is still just gibberish to my eyes.

Mainly I,m into traditional sculpture. Over the past ten years I have fallen in love with 3d modeling and sculpture. So I'm desperately trying to catch up and become fully proficient with the computer. I can't get enough. There is so much bad information out there. People learn something one day and write a half baked tutorial the next. Its hard for the novice to know who to listen to. Its plainly obvious to me that you REALLY know your stuff. Very nice.

Having the code annotated like this makes it very clear. It makes me want to search this sight for more of your annotated code. Of course I understand the value of working through things myself. I truly want to learn. Your help is like gold to me.

Many Thanks.
Find all posts by this user
Quote this message in a reply
Jan 9, 2012, 07:51
Post: #12
RE: Troubles duplicating a layer in a python script
(Jan 9, 2012 07:04)cavedog Wrote:  Having the code annotated like this makes it very clear. It makes me want to search this sight for more of your annotated code.
You won't find any Smile few people write their own scripts around here. Look on the Gimp registry for python scripts... you'll find good code and bad code, but since you can tell one from the other... My own scripts are mostly here and there (but not always as clean as above).

Now answering your questions on
https://Gimp-Forum.net
Visit this user's website Find all posts by this user
Quote this message in a reply
Post Reply 


Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Request for script chlebna 1 136 Sep 13, 2017 09:35
Last Post: ythgilb
  Request for script - Guillotine + Watermark sunslick 1 196 Sep 4, 2017 08:51
Last Post: ythgilb
  Script-fu: How to create new, addressable layer using gimp-floating-sel-to-layer Bertholom√§us 2 191 Aug 31, 2017 14:32
Last Post: Bertholomäus
  How to modify this script-fu? Zakary81 1 154 Aug 23, 2017 12:48
Last Post: paynekj
  Loading PythonFu Plugin: ImportError for .../python/gimp.so (GIMP 2.8.22/OSX/Py2.7.9) joroek 1 265 Jul 11, 2017 07:26
Last Post: ythgilb

Forum Jump:


GIMP ForumPortalArchiveContactTermsRSS