The best way to start is first to develop an PIL function which handles the manipulation. Afterwards you create input fields in order to pass the required parameters to the PIL function. Invert is taken as a first case study as it doesn't require any parameters except for the image itself. Let's look at the source code:
Example 1. Invert Action Source Code
from core import models #from core.translation import _t def init(): #lazy import global Image, ImageChops import Image, ImageChops #--- PIL function def invert(image,amount=100): #
inverted = ImageChops.invert(image) if amount < 100: inverted = Image.blend(image, inverted, amount/100.0) if image.mode == 'RGBA': inverted.putalpha(image.split()[-1]) return inverted #--- Phatch Action class Action(models.Action): #
label = _t('Invert') author = 'Stani' email = 'spe.stani.be@gmail.com' init = staticmethod(init) #
pil = staticmethod(invert) #
version = '0.1' tags = [_t('colours')] __doc__ = _t('Invert the colors of an image') #
def interface(self,fields): #
fields[_t('Amount')] = self.SliderField(100,1,100) icon = \ #
'x\xda\x01\x91\nn\xf5\x89PNG\r\n\x1a\n\x00\x00\x00...'
For every action you need to add the first two lines which import the basic functionality for writing action plugins. The module models provide the architecture for the plugin: the class Action
and the input fields.Every other module you need to import with the function init()
, in which you declare them as global. For example to invert an image with PIL you need the ImageChops
module.
![]() | |
Why do modules have to be imported in a seperate method? The reason is that Phatch at startup imports all actions to extract the information it needs about the actions. If the imports would be declared normally, the startup would be delayed by maybe unneeded modules. |
The PIL function should be defined separately from the action. This is a design choice, similar to splitting the Model from the View in the MVC approach.
You need to create a new class Action
which is derived from models.Action
. You need to define the action with the label
, author
, email
, init
, pil
, version
, tags
and doc
properties. label
and doc
will appear translated in the Add Action dialog box. That is why you need to mark them with the _t
function. We link our init and pil function as static methods to the class. (At the moment tags
and description
, which can contain a longer description than the doc
one-liner, are not exposed yet.)
In the description property you can describe the action more elaborately. Use triple quotes for multi-line text.
As in the example no specific icon was added, Phatch will use a default one. In the wxPython demo package (python-wxtools) there is an utility img2py.py
. With the following command you can convert any image (eg.png) to a python file:
$ python img2py.py fileName icon.py
This will generate an icon.py
file, in which you will find the following code:
def getData(): return zlib.decompress('icon data')
You can add now the icon data to your action source file to define the icon:
class Action(models.Action): description = """Invert the colors of the image.""" icon = 'icon data'
![]() | |
Internally Phatch works with photos. Photos consist of multiple layers. Every layer contains an image, but also has its own offset postion. Phatch doesn't expose this functionality yet, but will later support full layered photos, just like in Gimp. The hierarchy to remember is: Photo>Layer>Image. Luckily you don't have to worry about this in the beginning as Phatch provides you an easy method to apply a PIL function the current layer image: |
Probably looking at the source code of the actions, will teach you the most. You find all the actions in the folder phatch/actions
![]() | |
If you installed Phatch on Ubuntu, probably the actions are in the folder: |
Read the tutorial on the wiki.