[Image-SIG] Littlecms PIL module
spe.stani.be at gmail.com
Sat Feb 16 22:06:34 CET 2008
Frédéric Mantegazza wrote:
> I was looking for a littlcms python binding to make conversions between
> color spaces. This python binding already exists in littlecms, but it is
> not possible to convert entire images; as Marti explained, the goal is
> only to make numerical computations (one pixel at a time).
> As I was thinking to use PIL, Kent (from littlecms list) pointed me to
> an old (2002) discussion on the image-sig list, where Kevin Cazabon said
> he wrote a PIL module based on lcms. Unfortunally, this module does not
> seems to be maintained, and Kevin didn't answer (yet) to my e-mail.
> So, I looked at the code, which is simple, well written and well
> documented, and decided to modify it for my own use. For example, I wrote
> a (very simple) setup.py file to be able to compile and install the C
> module under linux; I also removed some functions, and added epydoc
> docstrings to generate nice html pages.
> This module seems to work fine, so it's maybe time to share it. As I didn't
> yet received an answer from Kevin, I won't put the code on a web site for
> now; just contact me if you want to try it.
> I said I adapted the code for my own use: I just need to make color space
> conversions, and maybe extract/assign profiles to images (this last part
> is not yet written; I have to look deeper in littlecms). Marti's python
> binding can do much more things (which I don't all understand, as my
> knowledge of color management is limited), so the goal is only to write
> things which does not exists. But I'm open to ideas and suggestions.
> Kent also pointed me to Phatch, a nice Photo Batch converter. So, my next
> goal is to make a Phatch action based on pyCMS, to convert images between
> color spaces (I'm looking for tutorial how to write actions, but it seems
> I have to look at existing actions code).
Phatch (PHoto bATCH processor & renamer) is in a way PIL exposed through
a cross-platform, user friendly GUI. It is comparable with imagemagic,
but comes with an optional GUI to make complex scripts easier and better
support to handle (sub)directories out of the box. It is part of Debian
unstable and Ubuntu Hardy (universe), but also supports Windows and Mac.
More info here:
To answer your question: writing actions for Phatch is very simple. Just
write a PIL function with this interface:
def pil(image, **keyw):
Afterwards you write an interface in a similar way like you would do in
Django for the keyw. Maybe a real world example is more useful, such as
the common colours action:
from core import models
from core.translation import _t
global Image, ImageFilter
import Image, ImageFilter
"""Apply a filter
- amount: 0-1"""
commoned = image.filter(ImageFilter.ModeFilter(radius))
if amount < 100:
return Image.blend(image, commoned, amount/100.0)
label = _t('Common')
author = 'Stani'
email = 'spe.stani.be at gmail.com'
init = staticmethod(init)
pil = staticmethod(common)
version = '0.1'
tags = [_t('filter')]
__doc__ = _t("Copies the most common pixel value")
fields[_t('Radius')] = self.RankSizeField(self.RANK_SIZES)
fields[_t('Amount')] = self.SliderField(100,1,100)
So it only takes four steps to write a Phatch action:
Import standard Phatch functionality (always the same two lines).
Group all other imports in an init function.
Write your PIL function
Wrap your PIL function in a Phatch Action class. It contains some
obvious information, such as author, etc... There are two important
1. You need to specify your pil function as a static method to your
2. You need to write the interface. As Phatch is multilingual, you need
to wrap the labels with _t(). Phatch has just like Django a complete
range of fields. These are some other possible fields (there are more,
fields[_t('Boolean')] = self.BooleanField(True)
fields[_t('String')] = self.CharField('hello world')
fields[_t('Choice')] = self.ChoiceField(CHOICES, CHOICES)
fields[_t('Colour')] = self.ColourField('#FFFFFF')
fields[_t('File')] = self.FileField('/home/images/logo.jpg')
fields[_t('Filename')] = self.FileNameField('<filename>')
fields[_t('In')] = self.FilePathField('<folder>') #folder
fields[_t('Float')] = self.FloatField(3.14)
fields[_t('As')] = self.ImageTypeField('<type>')#png, jpg
fields[_t('As')] = self.ImageReadTypeField('<type>')#png, jpg
fields[_t('Mode')] = self.ImageModeField('<mode>')#png, jpg
fields[_t('Resample')] = self.ImageResampleField(_t('bicubic'))
fields[_t('Integer')] = self.IntegerField(-4)
fields[_t('Integer+')] = self.PositiveIntegerField(0)
fields[_t('Integer+0')] = self.PositiveNoneZeroIntegerField(0)
fields[_t('Horizontal')]= self.PixelField('5%') #accepts %,cm, inch
fields[_t('Slider')] = self.SliderField(60,1,100)
The fields do behind the scenes different things like:
- validate the input
- interpolate or render image specific variables (such as <folder>,
<dpi>, <width>, <height>, but also EXIF and IPTC) during the process
- automagically create the GUI if Phatch is run as a GUI application
(Phatch can also run as a console application on image servers.)
I hope this get you started. Actually I would be more than willing to
help you to wrap your PIL function into a Phatch action, if you can
document it to make the process for other people easier. I really would
like to have this functionality in Phatch and I know already some
professionals eager to test it.
More information about the Image-SIG