############################################################################## # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER # OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ############################################################################## """ImageMixAdapter Implementation $Id:$ """ from zope.interface import implements from zope.app.file.image import Image from zope.app.file.interfaces import IImage from zope.app.annotation.interfaces import IAnnotations from zope.app.dublincore.interfaces import IZopeDublinCore from zope.component import adapts from interfaces import IImageMixAdapter import PIL.Image from PIL.ImageDraw import Draw from PIL import ImageFont from StringIO import StringIO import os,sys if sys.platform=='win32': fontpath = os.path.join(os.environ['SystemRoot'],'fonts','msgothic.ttc') else: raise NotImplementationError,'Please implement setup your system font path.' CIKey = 'imagemixadapter.imagemixadapter.ImageMixAdapter' class ImageMixAdapter(object): """Image Text mix adapter. Verify the interface implementation >>> from zope.interface.verify import verifyClass >>> verifyClass(IImageMixAdapter, ImageMixAdapter) True Create a mix-image of a Image >>> buf = StringIO() >>> PIL.Image.new('RGB',(1,1)).save(buf,'jpeg') >>> image = Image(buf.getvalue()) >>> mix = ImageMixAdapter(image) Only adopt, cooked_image have no data. >>> bool(mix.cooked_image) False Set Image to cooked_image, then ImageMixAdapter mix image and text. (but can't test that!) >>> mix.cooked_image = image >>> bool(mix.cooked_image) True IImageMixAdapter create another Image object. >>> mix.cooked_image == image False """ implements(IImageMixAdapter) adapts(IImage) def __init__(self, context): ''' ''' self.context = context def _setCookedImage(self, image): text = IZopeDublinCore(self.context).title if text: pi = PIL.Image.open(StringIO(image.data)) draw = Draw(pi) font = ImageFont.truetype(fontpath, 24) draw.text((0,0), text, font=font, fill=(0,0,0)) cooked = StringIO() pi.save(cooked, pi.format) cooked_image = Image(cooked.getvalue()) else: # Can NOT add to annotation its self cooked_image = Image(image.data) annotations = IAnnotations(self.context) annotations[CIKey] = cooked_image def _getCookedImage(self): annotations = IAnnotations(self.context) return annotations.get(CIKey) cooked_image = property(_getCookedImage, _setCookedImage) def changed_handler(event): image = IImage(event.object, None) if image: mix = IImageMixAdapter(image) mix.cooked_image = image