[Image-SIG] Littlecms PIL module

Stani spe.stani.be at gmail.com
Sat Feb 16 22:06:34 CET 2008


Frédéric Mantegazza wrote:
> Hello!
>
> 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).
>   
Hi Frédéric,
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:
http://photobatch.stani.be

To answer your question: writing actions for Phatch is very simple. Just 
write a PIL function with this interface:

def pil(image, **keyw):
  #manipulate image
  return image

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:

#1
from core import models
from core.translation import _t

#2
def init():
    global Image, ImageFilter
    import Image, ImageFilter
   
#3
def common(image,radius,amount=100):
    """Apply a filter
    - amount: 0-1"""
    commoned  = image.filter(ImageFilter.ModeFilter(radius))
    if amount < 100:
        return Image.blend(image, commoned, amount/100.0)
    return commoned

#4
class Action(models.Action):
    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")
   
    def interface(self,fields):
        fields[_t('Radius')] = self.RankSizeField(self.RANK_SIZES[0])
        fields[_t('Amount')] = self.SliderField(100,1,100)

So it only takes four steps to write a Phatch action:

#1
Import standard Phatch functionality (always the same two lines).

#2
Group all other imports in an init function.

#3
Write your PIL function

#4
Wrap your PIL function in a Phatch Action class. It contains some 
obvious information, such as author, etc... There are two important 
things here:
1. You need to specify your pil function as a static method to your 
Action class
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, 
see phatch/core/lib/formField.py):
        fields[_t('Boolean')]   = self.BooleanField(True)
        fields[_t('String')]    = self.CharField('hello world')
        fields[_t('Choice')]    = self.ChoiceField(CHOICES[0], CHOICES)
        fields[_t('Colour')]    = self.ColourField('#FFFFFF')
        fields[_t('Resolution')]= self.DpiField('<dpi>')
        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('As')]        = 
self.ImageWriteTypeField('<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.

Best regards,
Stani
--
http://pythonide.stani.be



More information about the Image-SIG mailing list