[Zope] Generating thumbnails on the fly using PIL

Lennart Regebro lennart@regebro.nu
Tue, 27 Nov 2001 13:42:56 +0100


This is a multi-part message in MIME format.

------=_NextPart_000_0003_01C17749.6BF7BB80
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

From: "Pieter Claerhout" <Pieter_Claerhout@CreoScitex.com>
> Hope that somebody can help with this.

Well, you can look at the attached product, it is an subclass of Image that
has thumbnails.
Actually, if you remove EasyResourcse and EasyDublinCore from the
constructor of the product, it should work in a standard Zope environment.

The code that does the resizing is this part:

    def makeimage(self, maxx=0, maxy=0, ratio=1, ftype='JPEG'):
        """Creates an image from the orginal with specified size."""

        if self.orig_data == None:
            tmpdata = self.data
        else:
            tmpdata = self.orig_data

        file = StringIO(str(tmpdata))

        if maxx <> 0 and maxy <> 0:
            im = PIL.Image.open(file)

            if ratio==1:            # keep aspect-ratio
                aspectx = float(im.size[0]) / float(maxx)
                aspecty = float(im.size[1]) / float(maxy)
                if aspectx > aspecty:
                    maxy = float(im.size[1]) / aspectx
                if aspectx < aspecty:
                    maxx = float(im.size[0]) / aspecty

            maxx = int(maxx)
            maxy = int(maxy)
            if im.mode!='RGB' and im.mode!='CMYK': im = im.convert("RGB")
            im.load()
            im = im.resize((maxx, maxy), PIL.Image.BICUBIC)

            newfile = StringIO()
            im.save(newfile, ftype, optimize=1)
            return newfile.getvalue(), TYPEINFOMAP[ftype]['content_type'],
im.size[0], im.size[1]

        return None, '', 0, 0

Hope it helps.


------=_NextPart_000_0003_01C17749.6BF7BB80
Content-Type: application/x-zip-compressed;
	name="EasyImage.zip"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
	filename="EasyImage.zip"

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
A3JeStW1ltxJ5Sk5gXmvy7SisHWDl17y2Ux9PQq9hgHigAaQo/dbHcf2XBAG0V7Awpm82PhZLCQh
QsDPWmccyKJfJnAx6RcAME2ZF2/BOye+ETaApbI352qiGxgBiojr2Tn9LkYaEIUnkDjZI4JsFOEp
Tdhtbda+h1wB++53bwbXr/E6nfe2+w45ZAJAkf5L73IRkoDPI0WWDJgQi9FFOKCzpbBjvxe/90C/
9YCdEDg3s78HYQC1qdFeBj+Zu57Z4cNSf5eGQrO1jgwPdW2yqPsMpFD6hWiatjD2kpkXlbRoNoYB
FuFwjOMdjuhp6d0q57XNUpLWL4X1Ap3noAd1WdO1TtV2WS6yeEDYd4WEpILOr6mSXcnaCDRvAQGY
bfftT9vJm7cKZCKM8JW+duuu3PRe1L6LmAx+z9npbjbr5rTCLpTjIgof6HgH8+MwzpbbDAQSxtgX
m5HDZCWnnyMoWfs8/zWZQQ4CTqkEFcEcgxb+KzeLHyai34aovHiJv8MVqP9dflGxrQaO8lcHW5GK
ng2RN+IjrISLoirWhFQeAFBLAQIUABQAAgAIABqZQyuSqIXrygEAAHQFAAAhAAAAAAAAAAEAAAAA
AAAAAABkdG1sL21hbmFnZV9hZGRFYXN5SW1hZ2VGb3JtLmR0bWxQSwECFAAUAAIACAAAm10rUimo
uxEDAAAhCQAAKwAAAAAAAAABAAAAAAAJAgAAZHRtbC9tYW5hZ2VfY29udmVydFJlc2l6ZUVhc3lJ
bWFnZUZvcm0uZHRtbFBLAQIUABQAAgAIAGixXCuwqQGg+wMAADQOAAAiAAAAAAAAAAEAAAAAAGMF
AABkdG1sL21hbmFnZV9lZGl0RWFzeUltYWdlRm9ybS5kdG1sUEsBAhQACgAAAAAAylRWKwAAAAAA
AAAAAAAAAAUAAAAAAAAAAAAAAAAAngkAAGR0bWwvUEsBAhQAFAACAAgA2XTqKvSIy8eaCQAAwRsA
ABMAAAAAAAAAAAAAAAAAwQkAAGljb25zL0Vhc3lJbWFnZS5wc2RQSwECFAAUAAIACADWdOoqZd7W
hT8CAABcAgAAEwAAAAAAAAAAAAAAAACMEwAAaWNvbnMvRWFzeUltYWdlLmdpZlBLAQIUAAoAAAAA
AMpUVisAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAPwVAABpY29ucy9QSwECFAAUAAIACACDUFAr
3CIhYkMFAABrDQAACwAAAAAAAAABAAAAAAAgFgAAX19pbml0X18ucHlQSwECFAAUAAIACAD4Yl4r
kSEDeMkXAAAQVQAADAAAAAAAAAABAAAAAACMGwAARWFzeUltYWdlLnB5UEsFBgAAAAAJAAkAVAIA
AH8zAAAAAA==

------=_NextPart_000_0003_01C17749.6BF7BB80--