Of Palettes and Plug-ins
This discussion is connected to the gimp-developer-list.gnome.org mailing list which is provided by the GIMP developers and not related to gimpusers.com.
This is a read-only list on gimpusers.com so this discussion thread is read-only, too.
Of Palettes and Plug-ins | Warren Turkal | 06 Sep 04:04 |
Of Palettes and Plug-ins | Chris Mohler | 06 Sep 04:11 |
Of Palettes and Plug-ins | Warren Turkal | 06 Sep 04:30 |
Of Palettes and Plug-ins | Chris Mohler | 06 Sep 17:11 |
Of Palettes and Plug-ins | Joao S. O. Bueno | 06 Sep 18:20 |
Of Palettes and Plug-ins | Warren Turkal | 07 Sep 06:20 |
Of Palettes and Plug-ins | Joao S. O. Bueno | 07 Sep 12:07 |
Of Palettes and Plug-ins | Warren Turkal | 07 Sep 23:49 |
Of Palettes and Plug-ins | Jon Nordby | 06 Sep 18:24 |
Of Palettes and Plug-ins | Joao S. O. Bueno | 06 Sep 20:16 |
Of Palettes and Plug-ins | Warren Turkal | 07 Sep 07:18 |
Of Palettes and Plug-ins | Joao S. O. Bueno | 07 Sep 12:15 |
Of Palettes and Plug-ins | Warren Turkal | 07 Sep 23:47 |
Of Palettes and Plug-ins | Alexandre Prokoudine | 06 Sep 20:18 |
Of Palettes and Plug-ins | Chris Mohler | 06 Sep 20:48 |
Of Palettes and Plug-ins | Warren Turkal | 07 Sep 05:09 |
Of Palettes and Plug-ins
Hey,
First of all, a little background. I am using the master branch and am trying to make the palette import parsers plugable. I have been experimenting a bit as a result.
I have been trying to write a python plugin that returns a palette. However, when I define a return type as PF_PALETTE, the pdb reports the procedure as returning a string. I have seen that PF_PALETTE is mapped to a PDB_STRING type. Further research suggests that a palette cannot be returned from a plugin procedure.
While discovering that, I also tried using the pattern used for file
importers to make the palette parsers importable. You can see my work so
far here.
This work is currently a bunch of hacking. As you can see
in gimp/app/plug-in/gimppluginmanager-file.c:278
(here),
I tried to use the GIMP_IS_PALETTE macro to make sure the return value of
the plugin is a palette. However, I cannot include "core/gimppalette.h" in
this file without lots of errors that I am not sure how to solve.
My basic design is going to be as follows:
- Add a procedure to register a palette loader This procedure will check that registered procedure take an int32 and two strings and return a palette. The args are the same as those for the image importer, and the return is a palette instead of an image. - Write a python (or other language) procedure to implement that interface.
Does anyone have any tips on making a procedure return a palette? Am I on the wrong course?
Thanks,
wt
Of Palettes and Plug-ins
On Thu, Sep 5, 2013 at 11:04 PM, Warren Turkal wrote:
Does anyone have any tips on making a procedure return a palette? Am I on the wrong course?
Don't know if this helps, but some years ago I wrote a plug-in to import palettes from Kuler (using Python): http://registry.gimp.org/node/10325
It's ugly as hell, but if you strip out all of the (admittedly hacky) color conversions maybe it will help. Basic gist is: open, convert, write GPL (gimp palette), refresh palette list.
Chris
Of Palettes and Plug-ins
Chris,
Thanks for the suggestion. I actually already found it, and it's been
pretty helpful. Unfortunately, it doesn't seem to import some ase's that I
have come across, like the ase ones
here.
However, I successfully been using it for some knowledge about the plugin
process.
When I first found that plugin, I was wondering why it created a new menu item in the palette menu. I found that it isn't possible to have plugins just provide a palette loader procedure and that the only way to integrate such a plugin was by creating ta new menu item that separately adds a palette.
That discovery seemed unfortunate to me, so now my goal is to make the process smoother by allowing one to write a plugin that will detect and load the file when it's selected through the normal import palette from file option. That "normal" method will have to change to allow plugins to be used in addition to the other palette loaders of course. It might even make sense to convert those palette loaders to plugins.
Just so you all know, this actually started with my wife wanting to import *.ase palettes in .
Later,
wt
Of Palettes and Plug-ins
On Thu, Sep 5, 2013 at 11:30 PM, Warren Turkal wrote:
Just so you all know, this actually started with my wife wanting to import *.ase palettes in .
Same here, but I just wanted to use Kuler palettes. Adobe claims the .ase specs are in the PS SDK, but if they are I never found them.
That's about as far down the rabbit hole as I got - I didn't feel like reverse-engineering the PS palette format.
Back to your main question: unless I'm out of touch, I believe all of the file loader plugins need to be written in C. I could well be wrong though. It's been quite some time since I touched anything having to do with GIMP besides the occasional plug-in in Python.
Chris
Of Palettes and Plug-ins
Hi -
Yes, the paramerter PF_PALETTE is passed around as a string - but that string is teh palette name in GIMP- teh palette is them usable with all palette -related PDB functions
There is no higher level Palette object on the Python side - and it makes little sens implementing one with the bindigns as they are now (it would require writting the pallete functionality in low-level C)
But having the string passed around between plug-ins works as nicely as it can be - I had written some palette creating/exporting a few years ago.
On 6 September 2013 14:11, Chris Mohler wrote:
On Thu, Sep 5, 2013 at 11:30 PM, Warren Turkal wrote:
Just so you all know, this actually started with my wife wanting to import *.ase palettes in .
Same here, but I just wanted to use Kuler palettes. Adobe claims the .ase specs are in the PS SDK, but if they are I never found them.
That's about as far down the rabbit hole as I got - I didn't feel like reverse-engineering the PS palette format.
Back to your main question: unless I'm out of touch, I believe all of the file loader plugins need to be written in C. I could well be wrong though. It's been quite some time since I touched anything having to do with GIMP besides the occasional plug-in in Python.
Chris _______________________________________________ gimp-developer-list mailing list
List address: gimp-developer-list@gnome.org List membership: https://mail.gnome.org/mailman/listinfo/gimp-developer-list
Of Palettes and Plug-ins
On 6 September 2013 19:11, Chris Mohler wrote:
On Thu, Sep 5, 2013 at 11:30 PM, Warren Turkal wrote:
Just so you all know, this actually started with my wife wanting to import *.ase palettes in .
Back to your main question: unless I'm out of touch, I believe all of the file loader plugins need to be written in C. I could well be wrong though. It's been quite some time since I touched anything having to do with GIMP besides the occasional plug-in in Python.
The OpenRaster file loader/saver (file-ora) is written in Python. It does not do any pixel manipulation of its own though.
Jon Nordby - www.jonnor.com
Of Palettes and Plug-ins
Besides - you have to check what makes more sense - I't think Palette exporting/importing plug-ins have to be on the Palletes context menu
My basic design is going to be as follows:
- Add a procedure to register a palette loader
There is no such thing as a "palette loader" - but there are plug-ins that
are registered under thhe "Palette" context menu. Ther is a sub-menu
named "Export as..." -
I think a loader should be under /Import/"
This procedure will check that registered procedure take an int32 and
two strings and return a palette. The args are the same as those for the
image importer, and the return is a palette instead of an image.
If it is a Python script, maybe you prefer using "PF_FILE" instead
of a string - that allows you to programatically pass a file path,
but the automatic
Python-fu interface would open a nice file dialog to use your plug-in directly.
- Write a python (or other language) procedure to implement that
interface.
Python recomended - some of the options in the Pallete context menu
are already in Python, copy one of them and it will be easier for you
to make your own.
And finally -as noted in the other e-mail I sent: the returend
"PF_PALETTE" is a string, but
a string corresponding to a unique name palette in GIMP, which is used
as ID for all Palette related
PDB calls.
js
-> wrote:
On 6 September 2013 19:11, Chris Mohler wrote:
On Thu, Sep 5, 2013 at 11:30 PM, Warren Turkal wrote:
Just so you all know, this actually started with my wife wanting to import *.ase palettes in .
Back to your main question: unless I'm out of touch, I believe all of the file loader plugins need to be written in C. I could well be wrong though. It's been quite some time since I touched anything having to do with GIMP besides the occasional plug-in in Python.
The OpenRaster file loader/saver (file-ora) is written in Python. It does not do any pixel manipulation of its own though.
-- Jon Nordby - www.jonnor.com
_______________________________________________ gimp-developer-list mailing list
List address: gimp-developer-list@gnome.org List membership: https://mail.gnome.org/mailman/listinfo/gimp-developer-list
Of Palettes and Plug-ins
On Fri, Sep 6, 2013 at 9:11 PM, Chris Mohler wrote:
On Thu, Sep 5, 2013 at 11:30 PM, Warren Turkal wrote:
Just so you all know, this actually started with my wife wanting to import *.ase palettes in .
Same here, but I just wanted to use Kuler palettes. Adobe claims the .ase specs are in the PS SDK, but if they are I never found them.
That's about as far down the rabbit hole as I got - I didn't feel like reverse-engineering the PS palette format.
Oh come on! :)
SwatchBooker reads pretty much all available palette formats. Surely you can read Python code :)
Alexandre
Of Palettes and Plug-ins
On Fri, Sep 6, 2013 at 3:18 PM, Alexandre Prokoudine wrote:
That's about as far down the rabbit hole as I got - I didn't feel like reverse-engineering the PS palette format.
Oh come on! :)
SwatchBooker reads pretty much all available palette formats. Surely you can read Python code :)
Well if I had a time machine when I was writing the plugin I surely would have hopped a year to two into the future and nicked the code ;)
And yeah, SwatchBooker makes the plug-in I wrote fairly obsolete - which is why I added a link to SB on the plugin page. I don't really need the .ase->.gpl conversion these days anyway.
Chris
Of Palettes and Plug-ins
On Fri, Sep 6, 2013 at 10:11 AM, Chris Mohler wrote:
On Thu, Sep 5, 2013 at 11:30 PM, Warren Turkal wrote:
Just so you all know, this actually started with my wife wanting to
import
*.ase palettes in .
Same here, but I just wanted to use Kuler palettes. Adobe claims the .ase specs are in the PS SDK, but if they are I never found them.
That's about as far down the rabbit hole as I got - I didn't feel like reverse-engineering the PS palette format.
I've seen some references to the format online. If it's as simple as it looks, I'll be okay. If not, at least I'll have fun.
Back to your main question: unless I'm out of touch, I believe all of the file loader plugins need to be written in C. I could well be wrong though. It's been quite some time since I touched anything having to do with GIMP besides the occasional plug-in in Python.
This knowledge is still current. The work I linked to in my original message was a start at trying to change that. I was trying to plumb through the ability to write plugins that could process files when you go through the normal import palette from file dialog.
Thanks, wt
Of Palettes and Plug-ins
On Fri, Sep 6, 2013 at 11:20 AM, Joao S. O. Bueno wrote:
Yes, the paramerter PF_PALETTE is passed around as a string - but that string is teh palette name in GIMP- teh palette is them usable with all palette -related PDB functions
I don't want to manipulate a current palette. I want to add code to gimp core to allow plugins to be written that could parse a palette file and return a palette object. The gimp core code would then use the returned palette object to add the palette to the list of palettes. If you want to get more specific, I want to add some code to the default case of the gimp_palette_import_from_file to attempt to load a palette using registered palette loader plugins. I'd like to be able to write them in Python, C, or whatever other languages are supported for Gimp plugins.
There is no higher level Palette object on the Python side - and it
makes little sens implementing one with the bindigns as they are now (it would require writting the pallete functionality in low-level C)
From the above comment, I assume that what I want to do will be hard. Any pointers on what would need to change to make it more useful? I'd be happy to try to do some of the work if it ends in making possible what I want to do.
But having the string passed around between plug-ins works as nicely as it can be - I had written some palette creating/exporting a few years ago.
Passing around a string doesn't really suit the use case I want to implement. I basically want the plugin to be able to return a palette that the core code registers if the running of the plugin is successful.
Are there any pointers for doing this kind of thing that I should be looking at?
Thanks,
wt
Of Palettes and Plug-ins
On Fri, Sep 6, 2013 at 1:16 PM, Joao S. O. Bueno wrote:
Besides - you have to check what makes more sense - I't think Palette exporting/importing plug-ins have to be on the Palletes context menu
My basic design is going to be as follows:
- Add a procedure to register a palette loader
There is no such thing as a "palette loader" - but there are plug-ins that are registered under thhe "Palette" context menu. Ther is a sub-menu named "Export as..." -
I think a loader should be under /Import/"
I would like to be able to follow the normal flow to importing a palette from a file like selecting "Import palette..." from the Palettes menu. Then click on the Palette file option. Then select the file. Click "Open", and it imports.
I don't want to have to add a menu option for each plugin that I add that can read a palette.
I also don't want each palette import plugin to have to write code to create a palette (in the gimp UI). I would rather be able to pass back some kind of palette object (like maybe a list of colors) and have the code within gimp to write that data into the palette within the gimp ui.
This procedure will check that registered procedure take an int32 and
two strings and return a palette. The args are the same as those for the image importer, and the return is a palette instead of an image. If it is a Python script, maybe you prefer using "PF_FILE" instead of a string - that allows you to programatically pass a file path, but the automatic
Python-fu interface would open a nice file dialog to use your plug-in directly.
Hmm. I see now that the Python-fu tries to do some UI magic. Is there some way to bypass that and write a plugin that allows passing in the parameters instead.
- Write a python (or other language) procedure to implement that
interface.
Python recomended - some of the options in the Pallete context menu are already in Python, copy one of them and it will be easier for you to make your own.
As mentioned above, I am interested in improving the Gimp infrastructure such that palette loaders can be implemented in a similar manner to file loaders.
And finally -as noted in the other e-mail I sent: the returend "PF_PALETTE" is a string, but
a string corresponding to a unique name palette in GIMP, which is used as ID for all Palette related
PDB calls.
I haven't found any way to make that interface work for what I am doing.
Basically, I need to be able to return a palette object, but not one in the
UI yet. That palette object can then be loaded by the existing gimp code
into a new palette in the UI. Note that this is a slightly simplified
description as all the current palette "loaders" return a GList* with only
one entry to a palette object. This code is
here
.
Thanks for the help,
wt
Of Palettes and Plug-ins
On 7 September 2013 03:20, Warren Turkal wrote:
On Fri, Sep 6, 2013 at 11:20 AM, Joao S. O. Bueno wrote:
From the above comment, I assume that what I want to do will be hard. Any pointers on what would need to change to make it more useful? I'd be happy to try to do some of the work if it ends in making possible what I want to do.
Let me say it again:
The "string" IS the Pallete as far as any code relating to GIMP via PDB is
concerned. It works more like an ID than as a name. And the PDB is
quite complete in what relates to Palette
manipulation.
Check this Python-fu Session - it creates a new palette and adds entries to it, just as you want:
GIMP 2.9.1 Python Console Python 2.7.3 (default, Jul 24 2012, 11:41:40) [GCC 4.6.3 20120306 (Red Hat 4.6.3-2)]
pal_id = "warren palette"
pal_id = pdb.gimp_palette_new(pal_id) print pal_id
warren palette
pdb.gimp_palette_add_color(pal_id, "black", (0,0,0))
Traceback (most recent call last):
File "", line 1, in
error: procedure not found
pdb.gimp_palette_add_entry(pal_id, "black", (0,0,0))
0
pdb.gimp_palette_add_entry(pal_id, "golden yellow", (255,230,0))
1
pdb.gimp_palette_add_entry(pal_id, "pinkish", (255,200,150))
2
And voilá- when I look in the Palette's dialog, in GIMP, the new
Palette _is there_,
with all three colors, fully featured as any other GIMP's palette
and with all the export options enabled for it.
Just take care with the line that goes:
pal_id = pdb.gimp_palette_new(pal_id)
It is important to store the ID as the return value of the call to
gimp_palette_new,
because it the palette name you attempt to create already exists, GIMP will
automatically modify the name with a numbering scheme - and the modified name
will be the ID for that pallete.
In practice, a Python Script manipulating Palletes never needs to do
anything with the
value passed around as a PF_PALETTE - (if it is a plug-in to
manipulate them in place, that is) -
it is just passed into the plug-in, and it is iused as an ID for all
Palette related calls.
BTW, it just occurred me that you might not yet be aware of the
procedure-browser functionality:
in GIMP, just open help->procedure browser - now type "palette" in the
search box -
there you are, all palette related calls available for your plug-in.
But having the string passed around between plug-ins works as nicely as it can be - I had written some palette creating/exporting a few years ago.
Passing around a string doesn't really suit the use case I want to implement. I basically want the plugin to be able to return a palette that the core code registers if the running of the plugin is successful.
Are there any pointers for doing this kind of thing that I should be looking at?
Thanks,
wt
Of Palettes and Plug-ins
On 7 September 2013 04:18, Warren Turkal wrote:
I haven't found any way to make that interface work for what I am doing. Basically, I need to be able to return a palette object, but not one in the UI yet. That palette object can then be loaded by the existing gimp code into a new palette in the UI. Note that this is a slightly simplified description as all the current palette "loaders" return a GList* with only one entry to a palette object. This code is here.
No, there is no such thing as a Palette object, but not one on the UI yet
in GIMP.
You create a new palette live, in GIMP.
If you need it not to appear in the objec, just maintain all palette
data in a data structure
in your own code.
(In python it would be a list of tuples - or a list of dictionaries if you need
better than O(N) access to an entry given its name or it's core value)
And you will need a function call to "commit" your data structure to
a palette in the UI when it is the time -
That would be about five lines of code, including
the function declaration.
If you want to access a non-UI visible GIMP Palette in several plug-ins, and want to use GIMP's palette PDB calls for that, you have to, in the same plug-in: commit your data to a new, temporary, GIMP Palette, do whatever you want with it (including exporting for an specific format by calling another plug-in), and remove it from GIMP's Palette list with pdb.gimp_palette_delete.
js ->
Of Palettes and Plug-ins
I thought that the palette loader code that is currently there created a palette before putting it in the UI. However, upon closer inspection, each of the loaders appear to create a palette based on the filename being imported, then the common code in gimp renames the object. Given that the current code isn't importing the palette atomically, I will just do the same thing. I think I see how to make this work.
This has been helpful.
Thanks, wt
On Sat, Sep 7, 2013 at 5:15 AM, Joao S. O. Bueno wrote:
On 7 September 2013 04:18, Warren Turkal wrote:
I haven't found any way to make that interface work for what I am doing. Basically, I need to be able to return a palette object, but not one in
the
UI yet. That palette object can then be loaded by the existing gimp code into a new palette in the UI. Note that this is a slightly simplified description as all the current palette "loaders" return a GList* with
only
one entry to a palette object. This code is here.
No, there is no such thing as a Palette object, but not one on the UI yet in GIMP.
You create a new palette live, in GIMP. If you need it not to appear in the objec, just maintain all palette data in a data structure
in your own code.
(In python it would be a list of tuples - or a list of dictionaries if you need
better than O(N) access to an entry given its name or it's core value) And you will need a function call to "commit" your data structure to a palette in the UI when it is the time - That would be about five lines of code, including the function declaration.If you want to access a non-UI visible GIMP Palette in several plug-ins, and want to use GIMP's palette PDB calls for that, you have to, in the same plug-in: commit your data to a new, temporary, GIMP Palette, do whatever you want with it (including exporting for an specific format by calling another plug-in), and remove it from GIMP's Palette list with pdb.gimp_palette_delete.
js ->
Of Palettes and Plug-ins
I already saw all those calls, I think I see how to modify my design to make it work. Thanks for the help! I am going to do some hacking and get another commit together.
Thanks, wt
On Sat, Sep 7, 2013 at 5:07 AM, Joao S. O. Bueno wrote:
On 7 September 2013 03:20, Warren Turkal wrote:
On Fri, Sep 6, 2013 at 11:20 AM, Joao S. O. Bueno wrote:
From the above comment, I assume that what I want to do will be hard. Any pointers on what would need to change to make it more useful? I'd be
happy
to try to do some of the work if it ends in making possible what I want
to
do.
Let me say it again:
The "string" IS the Pallete as far as any code relating to GIMP via PDB is concerned. It works more like an ID than as a name. And the PDB is quite complete in what relates to Palette manipulation.Check this Python-fu Session - it creates a new palette and adds entries to it,
just as you want:GIMP 2.9.1 Python Console Python 2.7.3 (default, Jul 24 2012, 11:41:40) [GCC 4.6.3 20120306 (Red Hat 4.6.3-2)]
pal_id = "warren palette"
pal_id = pdb.gimp_palette_new(pal_id) print pal_id
warren palette
pdb.gimp_palette_add_color(pal_id, "black", (0,0,0))
Traceback (most recent call last): File "", line 1, in
error: procedure not foundpdb.gimp_palette_add_entry(pal_id, "black", (0,0,0))
0
pdb.gimp_palette_add_entry(pal_id, "golden yellow", (255,230,0))
1
pdb.gimp_palette_add_entry(pal_id, "pinkish", (255,200,150))
2
And voil- when I look in the Palette's dialog, in GIMP, the new Palette _is there_,
with all three colors, fully featured as any other GIMP's palette and with all the export options enabled for it.Just take care with the line that goes:
pal_id = pdb.gimp_palette_new(pal_id)
It is important to store the ID as the return value of the call to gimp_palette_new,
because it the palette name you attempt to create already exists, GIMP will automatically modify the name with a numbering scheme - and the modified name
will be the ID for that pallete.In practice, a Python Script manipulating Palletes never needs to do anything with the
value passed around as a PF_PALETTE - (if it is a plug-in to manipulate them in place, that is) - it is just passed into the plug-in, and it is iused as an ID for all Palette related calls.BTW, it just occurred me that you might not yet be aware of the procedure-browser functionality:
in GIMP, just open help->procedure browser - now type "palette" in the search box -
there you are, all palette related calls available for your plug-in.But having the string passed around between plug-ins works as nicely as it can be - I had written some palette creating/exporting a few years ago.
Passing around a string doesn't really suit the use case I want to implement. I basically want the plugin to be able to return a palette
that
the core code registers if the running of the plugin is successful.
Are there any pointers for doing this kind of thing that I should be
looking
at?
Thanks,
wt