While I was repackaging my photo gallery application, I ran into
difficulties getting PIL bundled up with it. The application used PIL
to create thumbnails from JPEGs. I decide to try a different solution
instead of struggling with PIL.
MacOS X 10.3 comes with python 2.3. Apple also provided a python
wrapper around its
CoreGraphics
library, aka Quartz. I knew there was an easy way to use CoreGraphics to
resize images from reading
Andrew Shearer's The fastest way to resize images with Panther
.
My PIL replacement code is basically Andrew's code with a few additions
to make it behave more like PIL's Image.thumbnail():
import CoreGraphics
class JPEGImage:
def __init__(self, path):
"""A JPEG image.
Arguments:
path -- Path to a JPEG file
"""
self.path = path
self.image = CoreGraphics.CGImageCreateWithJPEGDataProvider(
CoreGraphics.CGDataProviderCreateWithFilename(self.path),
[0,1,0,1,0,1], 1, CoreGraphics.kCGRenderingIntentDefault)
self.width = self.image.getWidth()
self.height = self.image.getHeight()
def thumbnail(self, thumbnail, size):
"""Reduces a JPEG to size with aspect ratio preserved.
Arguments:
image -- pathname of original JPEG file.
thumbnail -- pathname for resulting thumbnail of image
size -- max size of thumbnail as tuple of (width, height)
"""
new_width, new_height = self.width, self.height
want_width, want_height = size
if new_width > want_width:
new_height = new_height * want_width / new_width
new_width = want_width
if new_height > want_height:
new_width = new_width * want_height / new_height
new_height = want_height
cs = CoreGraphics.CGColorSpaceCreateDeviceRGB()
c = CoreGraphics.CGBitmapContextCreateWithColor(new_width,
new_height, cs, (0,0,0,0))
c.setInterpolationQuality(CoreGraphics.kCGInterpolationHigh)
new_rect = CoreGraphics.CGRectMake(0, 0, new_width, new_height)
c.drawImage(new_rect, self.image)
c.writeToFile(thumbnail, CoreGraphics.kCGImageFormatJPEG)
# inplace replace our data with thumbnail's like PIL does
self.path = thumbnail
self.image = CoreGraphics.CGImageCreateWithJPEGDataProvider(
CoreGraphics.CGDataProviderCreateWithFilename(self.path),
[0,1,0,1,0,1], 1, CoreGraphics.kCGRenderingIntentDefault)
self.width = self.image.getWidth()
self.height = self.image.getHeight()
And that does everything I needed from PIL plus it makes the application
easier to build and smaller. Of course, it also means it will only work
on MacOS X 10.3 and not on previous versions. This is acceptable since
I'm just writing stuff for my own personal use.
|