← Back to team overview

phatch-dev team mailing list archive

Fwd: [Merge] lp:~jochym/phatch/Actions into lp:phatch

 

Hi Igor,

Could you review the tags of these new actions?
- warm up: 'filter'
- grid: 'size','compose','grid' (probably too much)

Hi Pawel,

We are very strict with the tags, thanks to Igors concerns. Igor is a
professional designer and provides valuable feedback for the user
experience.

Best regards,

Stani

PS I am thinking of merging your branch in a rush as 18/2/2010 is
Feature Freeze deadline for Ubuntu, as they involve new features. So
if there are any issues we can fix them later. No promises however.

---------- Forwarded message ----------
From: Paweł T. Jochym <pawel.jochym@xxxxxxxxxx>
Date: 2010/2/11
Subject: [Merge] lp:~jochym/phatch/Actions into lp:phatch
To: mp+19100@xxxxxxxxxxxxxxxxxx, stani <spe.stani.be@xxxxxxxxx>


Paweł T. Jochym has proposed merging lp:~jochym/phatch/Actions into lp:phatch.

   Requested reviews:
   stani (stani)


I have developed two fairly usefull actions:
- making grid of images (grid) and
- toning (warm_up).
They prove useful in the working photographer toolbox.
They are based on other actions from the repo and
are appropriatly licensed (GPL3).
I'll be glad if this code can be included in the phatch distribution.
I am new to the phatch development but tried to obey the rules.
=== added file 'phatch/actions/grid.py'
--- phatch/actions/grid.py	1970-01-01 00:00:00 +0000
+++ phatch/actions/grid.py	2010-02-11 14:10:26 +0000
@@ -0,0 +1,232 @@
+# Phatch - Photo Batch Processor
+# Copyright (C) 2007-2008 www.stani.be
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see http://www.gnu.org/licenses/
+
+# Embedded icon is designed by Igor Kekeljevic (http://www.admiror-ns.co.yu).
+# Based on standard Stani's actions
+# This action is (C) 2010 by Pawel T. Jochym <jochym@xxxxxxxxx>
+
+# Make m x n grid with copies of imput image
+
+from core import models
+from core.translation import _t
+from lib.imtools import has_transparency
+from math import sqrt
+
+#---PIL
+def init():
+    global Image
+    import Image
+    global HTMLColorToRGBA
+    from lib.colors import HTMLColorToRGBA
+
+def make_grid(image,grid,background_colour,old_size=None,scale=True):
+    #check if there is any work to do
+    if grid[0]==1 and grid[1]==1:
+        return image
+    #because of layer support photo size can be different from image layer size
+    if old_size is None:
+        old_size    = image.size
+    if scale :
+        # Keep the same number of pixels in the result
+        s=sqrt(grid[0]*grid[1])
+        old_size = tuple(map(lambda x: int(x/s) , old_size))
+        image=image.resize( old_size, getattr(Image,'ANTIALIAS'))
+
+    new_size=grid[0]*old_size[0],grid[1]*old_size[1]
+
+    #displacement
+    dx, dy = old_size
+    n, m = grid
+
+    #mode
+    if has_transparency(image) and image.mode != 'RGBA':
+        # Make sure 'LA' and 'P' with trasparency are handled
+        image = image.convert('RGBA')
+    else :
+        image = image.convert('RGB')
+
+    new_canvas  = Image.new(image.mode,new_size,background_colour)
+    
+    for x in range(n):
+        for y in range(m):
+            new_canvas.paste(image,(x*dx,y*dy))
+    
+    
+    return new_canvas
+
+
+#---Phatch
+class Action(models.Action):
+    label       = _t('Grid')
+    all_layers  = True
+    author      = 'Pawel T. Jochym'
+    email       = 'jochym@xxxxxxxxx'
+    init        = staticmethod(init)
+    pil         = staticmethod(make_grid)
+    version     = '0.2'
+    tags        = [_t('size'),_t('compose'),_t('grid')]
+    update_size = True
+    __doc__     = _t('Make n x m grid of image')
+    
+    def interface(self,fields):
+        fields[_t('Width')]                  = self.SliderField(1,1,8)
+        fields[_t('Height')]                 = self.SliderField(1,1,8)
+        fields[_t('Background Color')]       = self.ColorField('#FFFFFF')
+        fields[_t('Scale to keep size')]  = self.BooleanField(True)
+        
+    def values(self,info):
+        #size
+        x0, y0  = info['size']
+        x1  =   self.get_field('Width',info)
+        y1  =   self.get_field('Height',info)
+        grid = x1,y1
+        #parameters
+        return {
+            'old_size'      : (x0,y0),
+            'grid'      : grid,
+            'background_colour'   : self.get_field('Background Color', info),
+            'scale' : self.get_field('Scale to keep size', info),
+        }
+    
+    icon = \
+'x\xda\x01\xde\x0c!\xf3\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x000\x00\
+\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\x00\x00\x00\x04sBIT\x08\x08\x08\
+\x08|\x08d\x88\x00\x00\x0c\x95IDATh\x81\xd5\x98{l\x15\xd7\x9d\xc7\xbf\xe71\
+\xcf{\xaf_8\x18\x12\x1e1\x84\x90\xa6\xa0nK\x9bGE\x9b*m\xa1EU[5\x9b\x92\x18\
+\xb1\t\xc4\x0b!B%\xa0d\x1b\xb6dS\x08\xf2J(U\xb4E\x11\x8eS7\xe6aSbJ\xbdlD\x10\
+\xc2\xc4)\xb4\r\x84\x10\xd7\xc1IA8\x0e\x14\xfb:\xd8\x80\x1f\xb1\xef\xcc\x9ds\
+\xe6\xec\x1fw\xc6\x8c/\xd7\t\x8f\x95\xca\x8e\xf4\xd3\xd8s\xee\xcc\xf9~~\xbf\
+\xef\xef\x9c\xb9\x97(\xa5\xf0\xff\xf9\xa0\xffh\x01\xd7{\xf0\x7f\xb4\x80+9\
+\xaa\xab\xab\xbf$\x84\xf8\xaa\xe7y{\x96/_\x9e\x8c\x8e\x91\x1b\xd9B[\xb6l\x99\
+\xef\xfb\xfe\x7f\xf9\xbe_"\x84\x08/W.Y\xb2dY\xf8\xcf\r\x0b\xb0m\xdb\xb6\xdf1\
+\xc6\xe6{\x9e\x07\xcf\xf3 \xa5\x1c\x1e\x93R\x16-[\xb6\xec"p\x83\xf6@}}}\xa3m\
+\xdb\xf3\x01H!\xc4s\x8c\xb1q\x84\x90\xd7\xc2qM\xd3\x1e\x08\xff\xbe\xe1z\xa0\
+\xa1\xa1\xe1\xd9x<~\x7f___w*\x95\x9a\xbdx\xf1\xe2\x93\xc1\xd0\xfc\xaa\xaa\
+\xaa\x7f\x06@\xa5\x94}\xe1\xe7o\xa8\n\xec\xdb\xb7obaa\xe1/]\xd7UR\xca/G\xc4\
+\x03\x00\x18c.\x00\xd8\xb6\xfdVx\xed\x86\x02\xe0\x9c\xbf"\x84\xa0\x8e\xe34-X\
+\xb0\xa0#:\xb6m\xdb\xb62B\x88\x05\xe0\xe3\x85\x0b\x17\x9e\x0b\xaf\xdfP\x00\
+\xb6m\x7f\xc3q\x1c\xc5\x18+\xcb1\xfc\xa2\x10\x02J\xa9\r\xd1\x8b7\x12\x00\xa1\
+\x94\xdaB\x08\xf5\xe0\x83\x0fvE\x07v\xec\xd8Q-\xa5\x1c\x0b\xe0\xafK\x97.\xdd\
+\x14\x1d\xfb?\x01X\xbbv-\xdf\xbcy\xf3\xa6\xed\xdb\xb7\xdf{\xad\xcfhjj\x8a\t!\
+ \xa5\xa4555K\x00`\xfb\xf6\xed\xb7\xee\xdc\xb9\xf3\x8c\xe38\x8b]\xd7\x1db\
+\x8c\xdd\x9f}\xdfu\xef\x03[\xb7n-\xf5<\xef\x00\xa5\xf4VJ\xa9\xcf\x18[\xbb`\
+\xc1\x82u\xa7N\x9d\xbay```\x8d\xef\xfb\xcc\xf7\xfdNJ\xe9\xa9X,v\xf2\x8e;\xee\
+8\x01`\x00\xc0\x88\x89\xdfx\xe3\x8d[m\xdbnO&\x93H\xa5R\xb0,kH)e\x0e\x0e\x0eR\
+\xdf\xf7{)\xa53\xca\xcb\xcb;\xb2\xe7\xbf.\x80\x9a\x9a\x9a\xb2t:\xfd*\xa5To\
+\xf3\xdf\xc1D\xfd\x0b(-\x99\x8e[n\xb9\xc5K\xa7\xd3\xbc\xad\xad\x8d\x0c\x0e\
+\x0eB\xd34$\x12\t\xc4\xe3q\xd8\xb6\r\xc30\x14\xe7\xdcWJ\xc9T*\x95J&\x93\xe5\
+\xb1X\xec\x02!\xa4\xb1\xab\xab\x0b\x8e\xe3\x84S(BH\x93\xa6i?y\xf4\xd1G{si\
+\xb8\xa6}`\xed\xda\xb5|\xdc\xb8q5R\xca\x05\x8aI\x1cr\xb7\xe3\xa4\xfa\x0b\xfe\
+\xa5\xf4\x17(\x88\xdf\x8d\xc3\x87\x0fk\xd1\xc4p\xce\x91N\xa7\x91J\xa5\x00\
+\x00\xbe\xef\x13]\xd7\x99\x10\x829\x8e\xa3\x13B6\x12B\xde\xe9\xed\xed\x85\
+\xeb\xba\x00 \x01\xec\x97R.[\xb6lY\xfbgi\xb9\xea\n\xbc\xf4\xd2K\x93}\xdf\x7f\
+\x13@\xe9\xa7\xe4<\x1a\xc5op\x81t`\xc1\x1d\xff\x86/\xf1\xef\xe0\xa3\xb6\x91\
+\xf3q\xceaY\x16L\xd3\x84eY0\x0c\x03\xba\xaeC)\x05\xcf\xf3\xe08\x0eR\xa9\x94\
+\xd24\xad\xff\xdc\xb9s\xf9RJ\x07\xc0W\x97,Y\xd2z%z\xae\xaa\x02\x95\x95\x95\
+\x0f9\x8e\xb3\x991\xa6\x9fE+\xfe(k\xe1\xd1\x14\xcan\x7f\x1a\xd3\xbd\xd9\xf8\
+\xe8\xf4\xe5\xc9\xe2\x9c\x0f\x07\xa5\x14\x84\x10\x04\xcd\n\xd7u\xc3 \xfd\xfd\
+\xfd\xf9RJPJ\xbfV^^\x9eK<AV\xdf\\1@}}=K&\x93\xaf\xa6\xd3\xe9\x85\x84\x11\x1c\
+\x95\xaf\xe3\xb8\xdf\x08\xc2\x80\xfbo\xfe)\xbeH\xbe\x85\xb3\x9dgs\x8a\xd74\r\
+\x8c1P\x9aY\xf0\x82\xb5\x1c\x9e\xe7\r\xdb\xaa\xa7\xa7\x07\x03\x03\x03(..~\
+\xaf\xbc\xbc\xfcxx\xff\xc6\x8d\x1b\xf3\x0c\xc3\xf89\x80\x87\x01L\x00\xf0\x8e\
+\xef\xfb+\x1f\x7f\xfc\xf1#\xe1g>w\x19\xad\xad\xad\x9d\xd0\xd9\xd9yB\x08\xb1\
+\xd0c)\xec\x13\x95\xc3\xe2\'\xc5\xa7\xe3[\xf9e8\xfb\xf7\xcb\xc5\x87\x00Q\xf1\
+\xbe\xefC\x081\x9cy\xc7qp\xfe\xfcy\xb4\xb4\xb4`\xf6\xec\xd9p\x1c\xe7\xd3\xe0\
+V\xf2\xf2\xcb/?f\x18F\x1b\x80\x7f\x07P\n@\x03\xf0uJ\xe9\xe6\xaa\xaa*-\x9c\
+\xe33{\xa0\xba\xba\xfa\xc7CCC\xdb\x95R\xe6\'\xea#\xbc\x99~\x15C\xb4\x1f\x84\
+\x02\x84\x02\x8c2\x18\xcc\x86F\r\xe80\xc1\x1c\x13\xb2\xc7\x04\x1b4\xa1\x13\
+\x0bq3\x0fq+\x0f\t+\x0fE\xe6x\x8c\xd1\xc7\xc30\x0ch\x9a\xa6\x00\x10\xc7q\xf0\
+\xee\xbb\xefb\xe6\xcc\x99\x981c\x06ZZZ\xc0\x18\xfb-\xa5t\x86R\xea.\x00\x17\
+\x01\xd4\xfb\xbe\xbf\x83\x10r/!d=\x00PJ\xef,//\xff\x10\x18\xddB\xe4\x95W^yY\
+\x08Q\xce\x18#\xef\x8b\x038,\xff\x00\xc5}P\x92\xa9\x1b\xa1\x80\xa2\x12.\x1d\
+\x80K\x07 ]\xc0\xf9\x04Hu\x00\xd2\xcd\x18\x16\x0c\xa0\x1a@u\x80\x9a\xc0\xd8\
+\xc4\xcd\x98wS9JK\xa6\x931c\xc6$\x0f\x1f><p\xdbm\xb7\xdd\xde\xde\xde\x8et:\
+\x1dVmq\x90\xd43\x8e\xe3\xdc\xb5b\xc5\x8a\xee@SSeee\x99R\xea\xcet:\xad\x13B\
+\x88RJ]\x06P__?\xae\xaf\xaf\xef\x80R\xea\x0b>\xf5p ]\x83v\xf5^F\x0c\x05@2\
+\xe2C\x08B\x01_\x00^/\xe0\xf6\x00J\x02\xcc\xcc\x88f&\xc0\xf3\x00=\x1f\xd0\n\
+\x01?\xd6\x89&\xebE\x8c\xcb\xff\x0f\x14\xc4\xa6\x8e\x9f;w\xee\xf8c\xc7\x8e\
+\xa1\xa8\xa8\x08\xba\xaeKB\x08SJA)\x95r\x1c\xe7\x81\x95+W\xf6df\xca\xe4C\x08\
+1N)\xe5uuuu\x02 \x84\x90\x91\x16\xaa\xad\xad\xfd~:\x9d\xde\xa9\x94\xb2\xcf\
+\xfb\x1d\xd8\xeb\xbe\x84^\xf5IF4\t\x1eC.\t\x0f\xaf\x8b\x01`\xa83s\xa6\x06\
+\xa0\xe5\x07\x91\x00\x98}\t\x86r\x80p\x80P\x8a9V9\xbe\xa3\xff+\x08\x08\xce\
+\x9d;\xe7\x9e>}z\x83\x94\xf2Y\xa5\x14\xa4\x94\xab\x9e|\xf2\xc9\x8d\x11\xf1\
+\xe4\x89\'\x9e(\x996m\xda\xc7J\xa9\xa6U\xabV\xcd\x01\xe0\x03\xf0\xc3\n\x90\
+\xba\xba\xba\x17\x95R?\xe3\x9c\x93\xbfy\x7fF\xa3\xf8-\x04Kg\xee\x8e\x8a\x0f-\
+\x14\x9c\xa12V1o\xa2\xd0\'q\x18q\x0e\xcdd\xd0\x0c\x0e\xa2\x07\xa2\x03\xbb)"!\
+\x88\x80O<\xecs\xabpF\x1e\xc7\xc3\xe6z\x8c\x1d;\xd6\xc8\xcf\xcf\x7f\xec\xfd\
+\xf7\xdfG*\x95\x82\xe38\x07\x03{\xd3\x10b\xd2\xa4I+\xa5\x94p\x1cgsdf\xc2\x01\
+`\xeb\xd6\xad\x13\xa5\x94\x8f\x1b\x86A|\xe5#)O\xc0\xe7\xe9KKTT|\x14\x82\x02\
+\x9ci\x88\x99&t\xaeC\xd7\r\xe8\xba\x96Y}(\x03a4c;\n("\xa1\xa8\x84P\x02B\xa5!\
+T\x1a\x17U\'.\xaaN\xd8$\x0f\x8c\xb1\x9b9\xe7\xf0<O\xee\xd9\xb3\xa7-\x00`\x00\
+\xd8\xea\xd5\xab\x7f\n`\x85\xe7yMk\xd6\xac\xf9}\x04@\r[\xa8\xa2\xa2\xe2\x9f\
+\x8a\x8b\x8b\x1b\x0b\n\n\x8a\x00\xe0\xb8h\xc2\xfe\xf4o \xe1\xe5\xb4\x10%\x04\
+\x86n\xc3\xd2l\xe8\xdc\x84\xc9M\xe8\xdc\x00g:4\xae\x83S\x06\xca\x18(%\x00QPT\
+\xc1W\x02By\x10\xca\xc3xr;~\xa0\xaf\x80\xa9\x12\xe8\xed\xedEsss\xf5\xd0\xd0\
+\xd0c\x00D{{\xfb\xac\xaa\xaa\xaa\xb3\x13\'N\xb4\xe6\xcf\x9f\xff\xa3\x82\x82\
+\x82_\x11B>mmm\x9d[WW\xd7\x06@\x04!G\xf4\xc0\x86\r\x1b\x12\x96e\xfdOII\xc9}\
+\x9a\xa6\xe1\x13\xbf\x1d\xff\xedn\x18\xee\x83h\xf6m-\x06S\x8b\xc1\xd2b\xb0\
+\xb8\rC\xb3`p\x0b:7\xa01\x03\x1a\xe3`4\xb3\xfb\x82\x00\n\x19\x00\xa9\x04\xee\
+d\xf7a\x16\xfb\x01\xa0\x80\xd3\xa7O{\x87\x0e\x1dzd\xfd\xfa\xf5\xbb\x9f\x7f\
+\xfe\xf9n\xa5\x94\xa5\x94\xea\x12B\xbc\xc39\xff&!$_)\xd5}\xe2\xc4\x89\x07\
+\xeb\xea\xea>\x00\xe0\x05!\x00\x88\x9c\xfb\xc0\x0b/\xbc\xb0z\xc2\x84\t\xebc\
+\xb1\x18u1\x88\xdd\xe9\x17\xd1&\x8f\x0cC\x18\xdc\x84\xa5\xc5ak1XZ\x1cV\x00c2\
+\x1b\xa6fAg&tf\x80S\x0eJ9\x08\x08\x14\x14\x188\xbe\xc2\xe6a<\x99\x06!\x04\
+\x8e\x1d;\xd6\xfd\xdak\xaf}w\xd7\xae]\x7f\x07\x80g\x9eyf\x8da\x18+\xa3Z\x84\
+\x10\x07[[[\xd7444\x9c\x0cDG\x01\xe4\xa8\x1b\xd9s\xcf=wwii\xe9\xde\x92\x92\
+\x92\x02B\t\xfe$v\xa0)\xbd\x05 >,=\x8e\x98\x96\x80\xcd\x13\xb0\xf5x\x06\x86\
+\'`\xf1\x18L\x1e\x83\xc9m\x18\xcc\x82Fup\xa2\x83\x12\x8a8\x8a0\x93\x7f\x1b\
+\x16\x12\xe8\xef\xefGccc\xcb\xbau\xeb\x1e\xe8\xee\xeev\x91y\xfbDAA\x81^VV\
+\xf6\x93x<~\x9f\x94\xb2\xab\xbb\xbb\xfb\xcd-[\xb6\xfc)\x18\xcf\x16/\x00\xf89\
+\x01\x08\xc98~\xe9\xd2\xa5E3g\xce\xdc=u\xea\xd4{u]G\xbbz\x0f;\x9d\xf5P\x9a\
+\x8f\xb8\x96\x80\xad%\x10\xd3\xf2`\x870Z\x02\x16\x8b\x0f\x87\xc1,\xe8\xd4\
+\xc2x6\x05\xa5l\x16((\xce\x9c9\x83]\xbbv5UTT\xac\x8cf\x12#_\xd4\x14\x82e2"6*\
+\\\x06q9@(>\x08\x06\x80WTT<;c\xc6\x8c\x9f\x17\x16\x16\x92~t\xe3\x0f\xe2?q\
+\x91vf\xaa\xa0\xe5!\xc6\xf3\x10\xe3\t\xd8<\x0f\x16K \x16\x9eY>\xa6\xebw\xa3\
+\x84\x97B)\x85\xb7\xdf~\x1b{\xf7\xee=\xb4q\xe3\xc6_\x8c&(\x88\\\x19\xf7\xb2>\
+;r\x15\xca\x02\x08\xd7_-\x08\xe3\x91G\x1e\xf9\xfa\xdc\xb9s\xb7N\x992%N\xb8B\
+\xa3\xa8\xc6\x07x\x0b6O \xc6\xf2`\xb3\xbcL\x15X\x06\xa8\x88\x8f\xc7\x97\x8d\
+\xb9\xc8\xe77\xc1q\x1c\xbc\xfe\xfa\xeb8~\xfc\xf8_7m\xda\xb4ZJ\x19\n\x8f\x02\
+\x88,\xd1\xe9H\xe4\x14\xaf\x94\xca\t\x10\x8ag\x00\xf4 L\x00\xd6\xf4\xe9\xd3K\
+\x96/_^5k\xd6\xac;-\xcb\xc2\x07\xfe\x1f\xd1\xe4\xd7@\xa7\x06l\x1e@\xb0\x04n\
+\xd5g\xe2.\xe3\x870Y\x0c\xc9d\x12\r\r\r\xe8\xe9\xe9\xf9\xb8\xb6\xb6\xf6\xe9\
+\xbe\xbe>\'\x92\xed\xa8\xf8P\xb4\x0b\xc0\t\xcen\x16\x80\x1f\x15\x0f\xe4x\x1b\
+\r\x00\x182\x1b\xc9\xb0\xf808\xe7\xd6\xaaU\xab\x9e\x983g\xce\xc3\xc5\xc5\xc5\
+\xe4\x029\x8b=\xde\xaf\xe1\xd2A\xd8,\x81\xaf\x19?\xc4,\xe3{ \x84\xa2\xb9\xb9\
+\x19MMMp]\xb7{\xf7\xee\xddOwtt\xf4b\xa4\xbf\xa3\x99O\x07\xc2\x1d\x00\xa9 B\
+\x80h\x9f\x0c\x8b\xbf\x0c \x87}\xf4\xa8x\x00v\x00\xa4\xcf\x9b7o\xd6\xa2E\x8b\
+\xd6N\x9b6\xcd\xf4\xa8\x8b\xb7\xc4f|Q\xff&\xa6\xea_\x81\xe388p\xe0\x00N\x9e<\
+\t!\xc4\xc0\xc1\x83\x07W\x7f\xf8\xe1\x87\x1d\xa1\x80\x08D\x08\x10Z%\x95\x15n\
+v\xf6UV\xc6?\xab\x02!@\xb4\x02\xc3\x00\x00\xb4\xc9\x93\'\x8fy\xea\xa9\xa7\
+\x9e\xbf\xe7\x9e{\xa6\x18\x86\x01J)\xba\xba\xba\xb0\x7f\xff~\\\xb8p\x01\xbe\
+\xef\x0f577\xaf;z\xf4\xe8\xc9\x1c\xe2C\x0bE\xad\x13\x15\x1f\xda(\xcc\xbe\x9f\
+-\xfe\xb3\x00(.Y\xc8\x08\xc4\x9b\x91\xb3\x11\x8c\xf1\xc9\x93\'\x17-Z\xb4\xa8\
+j\xf6\xec\xd9\xb1\xce\xceN\x1c9r$\xfc=\xbf\xa7\xa5\xa5\xe5WG\x8e\x1c91\x8ax\
+\x89\x91\xcd\x1a\xb5N(~8\xfbJ)?[\xfch\x00\xa1\x8d\xa2U0\x02\xe1!\x84\x01@/,,\
+\x8c?\xf4\xd0C\xbff\x8cMe\x8cA\x08\x01\xdf\xf7\xd5\xd0\xd0\xd0[\r\r\r\x95}}}\
+n\xf0\xd8l\xdb\x84\xe2=\\jV\'\x12Q\xef\xfb\xa3e\x1f\x18\xfd\x1bY8\x99\xc0\
+\xa5=\x81D\xc6}\x00j\xca\x94)\x13\x07\x07\x07\x8fr\xce\xdb=\xcf\x1bp]\xb77\
+\x99L\x9e:x\xf0`+F\xfe\x8a\x10\xcdz\xae\xccGW\x9ep\xd5\x19\xde\x17F\x13\x0f\
+\x8c\xf2\x9d8\xb2\x991\x8c\\\x91\xc2j\x84\x151"\xd79\xb2\xde\xe1s\x88\xcf\
+\xf6|vd/\x999\x1b7z\xe4\xac\x80RJe\x18 \xa3\x97#\x0f\xcd\xce\xa8\x1f@\xf8Y\
+\x10\xd9\r\x1bf=\x97\xf0\xd02W,~T\x80\x1c\x10\n\xb9\x1b1;\xb4\xe0\xcc\xb2\
+\x00re\xde\xc1\xe5;m\xce\xcd\xea\x9a\x00\xb2 \xc2\x15 \n\x90\xdd\x94\x12\x19\
+K\xc9\xe0\xb9\xa1\x85\xa2k}\xae\xac{\xb8\xfc]\x08W"\xfes\x01r@|^%$.\xf5C\x14\
+ \xda\xb4\xd9\x96\x89\x8a\xbf\xa2\xac_\x15@\x08\x81\xccO\xdd\xa1\xa8\\;j\xb4\
+I\xc3>P\x18Y\x01\x0f\x9f\xf3rv5\xe2\xaf\x18 \nB\x08\xf1q)\xbb\xd9U\x08\xb3\
+\x1d\xf6\x00\xb2\xc0\xc2\xf3\x88\xac_\xab\xf8\xab\x06\x88@\x00\x97[*\x04\x08\
+\x97^\x12\x19\x0b!\xa2\xfdrM\x96\xb9n\x80,\x88p\xf2h%\xc2%\x14Yc\xd1&\xbd\
+\xae\xacG\x8f\xff\x05\xd8\xb6\xb3*\x16\xb11e\x00\x00\x00\x00IEND\xaeB`\x82\
+\xc6\x87\x0e\x81'

=== added file 'phatch/actions/warm_up.py'
--- phatch/actions/warm_up.py	1970-01-01 00:00:00 +0000
+++ phatch/actions/warm_up.py	2010-02-11 14:10:26 +0000
@@ -0,0 +1,161 @@
+# Phatch - Photo Batch Processor
+# Copyright (C) 2007-2008 www.stani.be
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see http://www.gnu.org/licenses/
+#
+# Phatch recommends SPE (http://pythonide.stani.be) for editing python files.
+
+# Embedded icon is designed by Igor Kekeljevic (http://www.admiror-ns.co.yu).
+# Based on Stani's colorize
+# This action is (C) 2010 by Pawel T. Jochym <jochym@xxxxxxxxx>
+
+# Make a colorized version of the image with midtone shifted to 
+# prescribed color value. 
+
+from core import models
+from core.translation import _t
+
+#---PIL
+def init():
+    global Image, ImageMath, ImageColor
+    import Image, ImageMath, ImageColor
+    
+def warmup(image,midtone,brighten,amount=100):
+    """Apply a filter
+    - amount: 0-1"""
+    if image.mode != 'L':
+        im      = image.convert('L')
+    else:
+        im      = image
+            
+    irgb=im.convert('RGB').split()
+    o=[]
+    m=ImageColor.getrgb(midtone)
+    b=brighten/600.0
+    # Calculate channels separately
+    for l in range(3):
+        o.append(ImageMath.eval(
+            "m*(255-i)*i+i", 
+            i=irgb[l].convert('F'), 
+            m=4*((m[l]/255.0)-0.5+b)/255.0 ).convert('L'))
+    
+    colorized = Image.merge('RGB',(o[0],o[1],o[2]) )
+    
+    if image.mode == 'RGBA':
+        colorized  = colorized.convert('RGBA')
+        colorized.putalpha(image.split()[-1])
+    
+    if amount < 100:
+        return Image.blend(image, colorized, amount/100.0)
+    
+    return colorized
+
+#---Phatch
+class Action(models.Action):
+    label       = _t('WarmUp')
+    author      = 'Pawel T. Jochym'
+    email       = 'jochym@xxxxxxxxx'
+    init        = staticmethod(init)
+    pil         = staticmethod(warmup)
+    version     = '0.2'
+    tags        = [_t('filter')]
+    __doc__     = _t('Warm up midtones of greyscale image')
+    
+    def interface(self,fields):
+        fields[_t('Midtone')]  = self.ColorField('#888888')
+        fields[_t('Brighten')]  = self.SliderField(0,0,100)
+        fields[_t('Amount')] = self.SliderField(100,1,100)
+
+    icon = \
+'x\xda\x01\x1f\x08\xe0\xf7\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00*\
+\x00\x00\x00*\x08\x06\x00\x00\x00\xc5\xc3\xc9[\x00\x00\x00\x04sBIT\x08\x08\
+\x08\x08|\x08d\x88\x00\x00\x07\xd6IDATX\x85\xcd\x98[lT\xc7\x19\xc7\x7fs\xce\
+\xd9\xb3g\xed\xdd\xb5\xbd`\x16\xb0\r,\xc1\x84D\x16\xc4B\xa9L\x13\xa9\xed\x03\
+(\x15Q\x93*\x12R\x93T"\xb1\x9dU\xd5\xa8Q\x1eKT\xd2(\xd0J\x95\x8a\xf2P\xa9u\
+\x95\xa0\x88bZT \xc5\x12\x94J\xc0K\xa3p7\x11\x11P9$\xb1Y\xd9\xeb\xa5+\xdbk\
+\xef\xed\\\xa7\x0f\xde5\xb6\xb1\r\x0e\x17\xf7\x93>\xcd\x99s\x99\xf9\xcd\xff\
+\x9b\x99ov\x91R\xf2\xff\xe4o\xbc\xf1F`\xa6\xfbBJ\xc9BZ<\x1e\xf7\x01/(\x8a\
+\xf2\xaa\xcf\xe7k\x06\x1al\xdb\xbe\xe9y\xde\x96\x8e\x8e\x8e\x9e\xf2{\xdaB\
+\x01\xb6\xb7\xb7\xaf\x03\xda|>\xdf\xf6\x8a\x8a\x8aE~\xbf\x1f)%\xb6m\xe38\xce\
+J\xe0%\xe0\xb7\x0b\x06\xda\xde\xde\xfe\xb4\x94rW0\x18\xdc\x12\n\x85\xd0u\x1d\
+\xc7q\xb0m\x1b\xd7u)\x14\n\x14\x8bE\x14E\xf9\xf7\xe4\xef\x1e\x19hkk\xebSR\
+\xca\xf7\xc3\xe1\xf0\xf3\xb5\xb5\xb5h\x9a\x86\xe388\x8e\x83\xeb\xba\xb8\xae\
+\xcb\xc8\xc8\x08\xf9|\x1eEQ\xbe\xf4\xf9|\x9f=R\xd0\xb6\xb6\xb6\'=\xcf{?\x1c\
+\x0e\xffx\xd9\xb2e\xc2\xef\xf7\xe3\xba.\xb6m#\xa5\x9cP3\x9dN\x93\xcf\xe7\x11\
+B8R\xca\x9fvttx\x8f\x04\xb4\xad\xadm\x99\xe7y\xbf\xab\xac\xac|9\x16\x8b)\x81\
+@\x00\xcf\xf3& =\xcf\xc3\xb2,L\xd3$\x99LR(\x14P\x14\x05EQv\x1f8p\xe0\xdc\xf4\
+\xf6\x1e8h<\x1e\xd7<\xcf\xfb\x85\x10\xe2\xd7\xb1X,TWW\x87\x94\x12\xd7u\'@\
+\x1d\xc7\xa1X,R(\x14H$\x12\x14\x8bE\x84\x10H)\xcf\x17\x8b\xc5\xf7gj\xf7\x81\
+\x82\xc6\xe3\xf1\x1f\xb8\xae\xfb\x87\xaa\xaa\xaa\'\xd7\xad[GEE\xc5Dx\xcb^\
+\x06\xccf\xb3\xf4\xf5\xf5a\x9a&\x00\xaa\xaa\xf6\xa9\xaa\xfaBWW\x97\xfb\xd0@\
+\xe3\xf1x=\xf0{\xd7u\xb7\xad]\xbb\x96\x95+W\xa2\xaa*\x9e\xe7a\x9a&\xb6mS(\
+\x14\xc8\xe7\xf3\xe4\xf3y2\x99\x0c}}}\xb8\xae\x8b\xaa\xaaH)\xd3\x8a\xa2l9t\
+\xe8\xd0\xe0l}\xdc\x17hWWW}OO\xcf/#\x91\xc8k\xa3\xa3\xa3\x81h4\xca\x9a5k\xf0\
+\xf9|\xd8\xb6\x8di\x9a\x14\n\x05r\xb9\x1c\xb9\\\x8el6K:\x9d&\x91H\xa0i\x1a\
+\x86a\x00\xe4\x02\x81\xc0\x8b\xfb\xf7\xef\xef\x99\xab\xafo\x95\x99\x8e\x1d;\
+\xb6\xd1\xf3\xbc?VVV>\x1d\x08\x04\xd0u\x1d\xd34I\xa7\xd3|\xf3\xcd7\x18\x86A \
+\x10 \x9f\xcf\x93\xcdf\' \x93\xc9$\x83\x83\x83\xe8\xbaN(\x14BJi\x1b\x86\xf1\
+\x93}\xfb\xf6\x1d\x01\xe6\x04\x99\xb7\xa2]]]\xaf9\x8e\xf3g\xd34\xb5\xf2\x96b\
+\x18\x06\x9b6mb\xfd\xfa\xf5\xb8\xae\xcb\xb9s\xe78y\xf2$\x91H\x84\\.G&\x93\
+\xe1\xe6\xcd\x9bd2\x19\x82\xc1 \xa1P\x08\xc7q<]\xd7\xdf~\xec\xb1\xc7>\xb9\
+\x1b$\xccS\xd1\xce\xce\xce\xce\xa1\xa1\xa1\x97\x01*++ill\xa4\xa6\xa6\x06\xc3\
+0(\x16\x8b\xf4\xf6\xf6\xf2\xec\xb3\xcf\x92\xc9d\xb8r\xe5\n\x87\x0f\x1f\xc6q\
+\x1c\x06\x06\x06\x10B\x10\x0e\x87\t\x85B\xe5\xadh\xf7\xc1\x83\x07w\x02\xde]\
+\xba\x9d\x1f\xe8\x8e\x1d;\xde\xbap\xe1\xc2\x07###X\x96\x85a\x18,Y\xb2\x84\
+\x96\x96\x16\xb6n\xddJSS\x13\xb7n\xdd\xe2\xc4\x89\x13l\xd8\xb0\x81|>Oww7\x87\
+\x0f\x1fF\xd34\x16-ZD0\x18dtt\x14\xc7q\xf6\x1e=z\xb4\xfd^!\xef\t4\x16\x8bU[\
+\x96\xf53]\xd7w[\x96%\xa4\x94\x84\xc3a\x82\xc1 CCC8\x8eC4\x1a\xe5\xcd7\xdf\
+\xe4\x99g\x9e!\x99Lr\xea\xd4)6o\xdeLOO\x0f\x9f~\xfa)\xa9T\x8aH$\xc2\xd8\xd8\
+\x18\xa6i\x1e;~\xfc\xf8\x8f\xe6\x03\t\xa0\xcc\xf5p\xc5\x8a\x15\xcbkjj\xfeS[[\
+\xfb\x9bB\xa1 L\xd3\xa4\xae\xae\x8e\'\x9exb\xe2\x00\x91\xcdf\xb9q\xe3\x06;w\
+\xee\xe4\xc3\x0f?\xc4u]\x1e\x7f\xfcq:::0M\x13\xcf\xf3\xc8f\xb3\xa4R)\xc6\xc6\
+\xc6\xceo\xdb\xb6\xed\xc5\xf9B\xce\t\xda\xd8\xd8\xe8\xaf\xae\xae\xeejjj\x8a\
+\x0e\x0f\x0fcY\x16\x1b7nd\xd3\xa6M\xa4R)\x06\x07\x071M\x13!\x04\x9a\xa6\x91\
+\xcdf9p\xe0\x00\x17/^d``\x00\xc7q\xb8t\xe9\x12_\x7f\xfd5\x8a\xa20::z\xbd\xa9\
+\xa9\xe9{\xdb\xb7ow\xe6\x0b\ts\x84\xbe\xae\xae\xee\xa3h4\xfa\xfa\xf0\xf00###\
+477\xd3\xdc\xdc\xcc\xe5\xcb\x97\xb9~\xfd\xfa\x04di/\xc4\xf3<\x8a\xc5"\x8d\
+\x8d\x8d<\xf7\xdcs\x9c={\x96\xbe\xbe>4Mc\xf9\xf2\xe5I\xd7u\xd7\x9e>}:\xfbm a\
+\x16E\xeb\xeb\xeb7\xa8\xaa\xfaz\xa1P \x93\xc9\x10\x89D\xa8\xad\xad\xe5\xcc\
+\x993\\\xbbv\r\xd34Q\x14\x85\x86\x86\x06V\xacX\x010\xfesA\x08\x12\x89\x04\
+\xd9l\x96\xde\xde^\xfa\xfb\xfb)\x16\x8b444\xbct?\x900\xcb>*\xa5l\x05H\xa7\
+\xd3\xa8\xaaJ$\x12\xe1\xea\xd5\xab\xa4\xd3i,\xcbBUUV\xadZ\xc5\xd2\xa5K\xf9\
+\xfc\xf3\xcf\'\x8ej\xba\xae#\x84\xc0\xb6m\xc6\xc6\xc60\x0c\x83\x96\x96\x96\
+\xbf\xef\xdd\xbb\xf7\xcc\xfd@\xce\n\x9a~5\xfdj\xf8D\x18/\xe7\xe1\xf7\xfbI&\
+\x938\x8e\x83i\x9a\xe8\xbaN}}=\x9e\xe7\xd1\xdd\xdd\x8deY8\x8e\x83\xae\xeb\
+\xa8\xaa\x8aa\x18\x08!X\xbcx1\xb1X\xec_\x9d\x9d\x9d\xdb\xee\x17\x12f\x98\xa3\
+\xe2=Q\xcdw\x19\x16\xff\x14(\x8d\n\xb2AR\xf3N\r^\xc2C\xd7u\x82\xc1\xe0\xc4\
+\x8a\xb7,\x0b\x00\x9f\xcf\x87\xa6\x8d\x8fy\xfd\xfa\xf5,]\xba\x14]\xd7wutt\
+\xfc\xeaA@\xc2L\x8a*\xac$\x012 q[]\xf8+\x0c\xad\x1d\xa2bI\x05\xd2\x95\xc8[\
+\x12/\xe5\xe18\x0e\x9a\xa6\xe1\xf3\xf9\x10B\x00\xb0z\xf5j\xa2\xd1h\xae\xa6\
+\xa6f\xfb\x9e={\x0e=(\xc8\x99A%\xab\xb8\x06\xbc\x02\x1c\x01\xce\x82\\\'\xc9\
+\xa99\xc8\x80\xfa\x95J\xf5\x7f\xab1\x0c\x03EQ(EDVUU\xfd%\x1a\x8d~\xf0\xf1\
+\xc7\x1f_~\x90\x80e\xbb3\xf4\xef\x8a\xfd\x14y\x85\n`\rP\x0f\xf4\x00\xdd\x80\
+\n\x84@1\x15\xaa\x8eW\xa1\ri\xf8|\xbe\xcf\xa4\x94o\r\x0c\x0c\\|\x18\x803\x82\
+\x8a\xf7\xc4b\xaa\x18d\t*\xd5@\x02\x18\x00,\xc0)\xb9\r\x98\x10\xbe\x1a\x1e\n\
+\xf6\x05\x7f\xde\xdf\xdf\xff\xb7\x87\tX\xb6\xe9\xa1o\x11\xcb\x85-\x13R\xe5Kn\
+\x1f\xbe\x8c\xf1ka\x8ba\xe1\x89^\xc2\x9c\x1f}~\xf4\xdd\xcc\x8eL\xeaQ@\xc2\
+\xcc\xab^\x01\x9e\x02"\x80\x8e@ \xe9#\xccW\xf2mYxT`\xd3m\xc1\xff{\xbaW\x9b\
+\x92B\x05B\x08G|\x7f\x81X\xe6\xb4\xa9\xb9>E+C|\xb4@,s\xdaT\xd0\x02\xef\xe0\'\
+&\xae\x88\x96\x05\xe2\x99\xd5&@\xc5\x17\xa2\x06\x8f\x95\x84\x11d\xd9\'\x10s\
+\x1e\xaa\x1f\xb5\xdd\x86I\xb1\x99\x1b\x08\xfa\x81\x9b4\xf2\x0fv-\x1c\xd6\x9d\
+v{\x1f\x1d#O/\xf0\x05\xe0\x02\xd5|g\xbe\x8d\x95s\xfe\xc3\xd8I\xa6f\xa6?\x89#\
+\xa4\xf9!\x01\x12\x84x\x8d8\x17\xca\x8f\xa6\x95\xccR\x87\xf14!\xef\xe1zJy\
+\xb7\xc1\x89\xd2\xc9\\a<\xff\xf8XL\x804*\xa03\xae\xb8(\xb92\x0bp\x19\xc0\x9b\
+T\x96\xdd\x9d\xa1\xee\xce\xf2\xac\xec\x13mN\x11\xb1T\x06\x81\xb5\xc0\x12\xc0\
+_\x82R&\x7f4\xcd\xa77>\x1d`.w\xeeR\x9f\xd2F\x99\xb6\xacX\x00XTr\x7f\xe9\xfed\
+\xd0\x99\xa0\xee\xb5\xf3\xe9\xd7\xda\xb4{\xea\xa4z\xb9\x9c,\x90\x0b\xb7C\xef\
+\x03\xc2%\xaf,y\xc5$u\xcb\xe1\x87\x99C<=\xd4wS\xf5n\x83r\xca\xfd\x94\x15\x9d\
+XL\xa5\x15\xab\x96F\xac\x96|\xfa\xbc\x9c\xcb\x99T\x96\x95\x98i0\x93\x07:\xd3\
+b\xbbc~\x02\xfc\x0f\'\xc4\x97\xb6\x97\xab\xbe\x05\x00\x00\x00\x00IEND\xaeB`\
+\x82`8\xef\xcc'


References