1 # -*- coding: utf-8 -*-
2 ############################################################
3 # Copyright © 2005-2008 Benoît PIN <benoit.pin@ensmp.fr> #
4 # Plinn - http://plinn.org #
6 # This program is free software; you can redistribute it #
7 # and/or modify it under the terms of the Creative Commons #
8 # "Attribution-Noncommercial 2.0 Generic" #
9 # http://creativecommons.org/licenses/by-nc/2.0/ #
10 ############################################################
12 $Id: composite.py 1225 2009-07-25 21:52:23Z pin $
13 $URL: http://svn.luxia.fr/svn/labo/projects/zope/Portfolio/trunk/Extensions/composite.py $
16 from AccessControl
import Unauthorized
17 from PIL
.Image
import new
as newImage
, open as imgopen
, composite
18 from cStringIO
import StringIO
20 def compositeSolidColor(self
, image
, mask
, color
=0xffffff
21 , margin_right
=0, margin_bottom
=0
22 , margin_left
=0, margin_top
=0) :
24 if iw
> 800 or ih
> 800 :
25 raise Unauthorized
, "You are not allowed to get an image larger than 800px"
26 mask
= imgopen(StringIO(mask
))
27 assert mask
.mode
=='L', "mask must be in L mode"
31 if margin_right
and margin_bottom
:
32 box
= (iw
-mw
- margin_right
, ih
-mh
- margin_bottom
, iw
- margin_right
, ih
- margin_bottom
)
34 box
= (margin_left
, margin_top
, margin_left
+mw
, margin_top
+mh
)
36 tile
= image
.crop(box
)
38 coloredImage
= newImage('RGB', mask
.size
, color
)
40 mergedImage
= composite(coloredImage
, tile
, mask
)
42 image
.paste(mergedImage
, box
)
46 def outline(self
, image
, mask
, distance
=128
47 , margin_right
=0, margin_bottom
=0
48 , margin_left
=0, margin_top
=0) :
50 if iw
> 800 or ih
> 800 :
51 raise Unauthorized
, "You are not allowed to get an image larger than 800px"
53 mask
= imgopen(StringIO(mask
))
54 assert mask
.mode
=='L', "mask must be in L mode"
57 if margin_right
and margin_bottom
:
58 box
= (iw
-mw
- margin_right
, ih
-mh
- margin_bottom
, iw
- margin_right
, ih
- margin_bottom
)
60 box
= (margin_left
, margin_top
, margin_left
+mw
, margin_top
+mh
)
61 tile
= image
.crop(box
)
63 lumAverage
= getLumAverage(tile
)
65 gray
= lumAverage
- distance
67 gray
= lumAverage
+ distance
71 color
= gray
+ (gray
<<8) + (gray
<<16)
72 coloredImage
= newImage('RGB', mask
.size
, color
)
73 mergedImage
= composite(coloredImage
, tile
, mask
)
75 image
.paste(mergedImage
, box
)
79 def getLumHistogram(im
) :
80 histo
= im
.histogram()
81 layers
= len(histo
) / 256
84 shifts
= [i
*256 for i
in range(layers
)]
86 for i
in xrange(256) :
87 indexes
= [n
+i
for n
in shifts
]
88 tot
= reduce(lambda a
, b
: a
+b
, [histo
[p
] for p
in indexes
])
89 tot
= int(round(tot
/ float(layers
)))
95 def getLumAverage(im
) :
96 lHisto
= getLumHistogram(im
)
98 for i
in xrange(256) :
101 L
= float(L
) / reduce(lambda a
,b
: a
+ b
, lHisto
)