[Checkins] SVN: z3c.filetype/trunk/src/z3c/filetype/ added specific
size adapters
Bernd Dorn
bernd.dorn at fhv.at
Wed Aug 30 12:27:58 EDT 2006
Log message for revision 69893:
added specific size adapters
Changed:
U z3c.filetype/trunk/src/z3c/filetype/README.txt
U z3c.filetype/trunk/src/z3c/filetype/configure.zcml
U z3c.filetype/trunk/src/z3c/filetype/magic.txt
U z3c.filetype/trunk/src/z3c/filetype/size.py
A z3c.filetype/trunk/src/z3c/filetype/testdata/IMG_0504.JPG
-=-
Modified: z3c.filetype/trunk/src/z3c/filetype/README.txt
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/README.txt 2006-08-30 15:44:42 UTC (rev 69892)
+++ z3c.filetype/trunk/src/z3c/filetype/README.txt 2006-08-30 16:27:55 UTC (rev 69893)
@@ -24,6 +24,8 @@
... print i
DS_Store
set([<InterfaceClass z3c.filetype.interfaces.filetypes.IBinaryFile>])
+ IMG_0504.JPG
+ set([<InterfaceClass z3c.filetype.interfaces.filetypes.IJPGFile>])
faces_gray.avi
set([<InterfaceClass z3c.filetype.interfaces.filetypes.IAVIFile>])
ftyp.mov
@@ -181,3 +183,37 @@
[<InterfaceClass z3c.filetype.interfaces.filetypes.IQuickTimeFile>]
>>> interfaces.IFileType(foo).contentType
'video/quicktime'
+
+Size adapters
+=============
+
+There are adapters registered for ISized for IPNGFile, IJPEGFile and
+IGIFFile.
+
+ >>> from z3c.filetype import size
+ >>> from zope.size.interfaces import ISized
+ >>> component.provideAdapter(size.GIFFileSized)
+ >>> component.provideAdapter(size.PNGFileSized)
+ >>> component.provideAdapter(size.JPGFileSized)
+
+ >>> foo.data = file(os.path.join(testData,'thumbnailImage_small.jpeg'))
+ >>> notify(ObjectModifiedEvent(foo))
+ >>> ISized(foo).sizeForDisplay().mapping
+ {'width': '120', 'height': '90', 'size': '3'}
+
+ >>> foo.data = file(os.path.join(testData,'test.png'))
+ >>> notify(ObjectModifiedEvent(foo))
+ >>> ISized(foo).sizeForDisplay().mapping
+ {'width': '279', 'height': '19', 'size': '4'}
+
+ >>> foo.data = file(os.path.join(testData,'logo.gif'))
+ >>> notify(ObjectModifiedEvent(foo))
+ >>> ISized(foo).sizeForDisplay().mapping
+ {'width': '201', 'height': '54', 'size': '2'}
+
+ >>> foo.data = file(os.path.join(testData,'IMG_0504.JPG'))
+ >>> notify(ObjectModifiedEvent(foo))
+ >>> ISized(foo).sizeForDisplay().mapping
+ {'width': '1600', 'height': '1200', 'size': '499'}
+
+
Modified: z3c.filetype/trunk/src/z3c/filetype/configure.zcml
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/configure.zcml 2006-08-30 15:44:42 UTC (rev 69892)
+++ z3c.filetype/trunk/src/z3c/filetype/configure.zcml 2006-08-30 16:27:55 UTC (rev 69893)
@@ -14,7 +14,9 @@
<adapter factory=".adapters.TypedFileType"/>
- <adapter factory=".size.ImageFileSized" />
+ <adapter factory=".size.PNGFileSized" />
+ <adapter factory=".size.JPGFileSized" />
+ <adapter factory=".size.GIFFileSized" />
</configure>
Modified: z3c.filetype/trunk/src/z3c/filetype/magic.txt
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/magic.txt 2006-08-30 15:44:42 UTC (rev 69892)
+++ z3c.filetype/trunk/src/z3c/filetype/magic.txt 2006-08-30 16:27:55 UTC (rev 69893)
@@ -14,6 +14,7 @@
... path = os.path.join(testData, name)
... print name, m.detect(file(path))
DS_Store set([])
+ IMG_0504.JPG set(['image/jpeg'])
faces_gray.avi set(['video/x-msvideo'])
ftyp.mov set(['video/quicktime'])
jumps.mov set(['video/quicktime'])
Modified: z3c.filetype/trunk/src/z3c/filetype/size.py
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/size.py 2006-08-30 15:44:42 UTC (rev 69892)
+++ z3c.filetype/trunk/src/z3c/filetype/size.py 2006-08-30 16:27:55 UTC (rev 69893)
@@ -1,30 +1,45 @@
from zope.size.interfaces import ISized
-from zope.app.file.image import getImageInfo
+
from zope.size import byteDisplay
-from interfaces.filetypes import IImageFile
+from interfaces import filetypes
from zope import component, interface
from zope.app.i18n import ZopeMessageFactory as _
+import os
+import stat
+import struct
class ImageFileSized(object):
+
interface.implements(ISized)
- component.adapts(IImageFile)
def __init__(self, image):
self._image = image
+ @property
+ def bytes(self):
+ try:
+ return len(self._image.data)
+ except TypeError:
+ data = self._image.data
+ return int(os.fstat(data.fileno())[stat.ST_SIZE])
+ raise NotImplementedError
+
def sizeForSorting(self):
'''See `ISized`'''
- return ('byte', self._image.getSize())
+ return ('byte', self.bytes)
+ def getImageSize(self):
+ raise NotImplementedError
+
def sizeForDisplay(self):
'''See `ISized`'''
- t, w, h = getImageInfo(self._image.data.read(256))
+
+ w, h = self.getImageSize()
if w < 0:
w = '?'
if h < 0:
h = '?'
- bytes = self._image.getSize()
- byte_size = byteDisplay(bytes)
+ byte_size = byteDisplay(self.bytes)
mapping = byte_size.mapping
if mapping is None:
mapping = {}
@@ -32,3 +47,83 @@
#TODO the way this message id is defined, it won't be picked up by
# i18nextract and never show up in message catalogs
return _(byte_size + ' ${width}x${height}', mapping=mapping)
+
+
+class GIFFileSized(ImageFileSized):
+
+ interface.implements(ISized)
+ component.adapts(filetypes.IGIFFile)
+
+ def getImageSize(self):
+ data = self._image.data
+ data.seek(0)
+ data = data.read(24)
+ size = len(data)
+ width = -1
+ height = -1
+ if (size >= 10) and data[:6] in ('GIF87a', 'GIF89a'):
+ # Check to see if content_type is correct
+ w, h = struct.unpack("<HH", data[6:10])
+ width = int(w)
+ height = int(h)
+ return width, height
+
+class PNGFileSized(ImageFileSized):
+
+ interface.implements(ISized)
+ component.adapts(filetypes.IPNGFile)
+
+ def getImageSize(self):
+ data = self._image.data
+ data.seek(0)
+ data = data.read(24)
+ size = len(data)
+ height = -1
+ width = -1
+ # See PNG 2. Edition spec (http://www.w3.org/TR/PNG/)
+ # Bytes 0-7 are below, 4-byte chunk length, then 'IHDR'
+ # and finally the 4-byte width, height
+ if ((size >= 24) and data.startswith('\211PNG\r\n\032\n')
+ and (data[12:16] == 'IHDR')):
+ w, h = struct.unpack(">LL", data[16:24])
+ width = int(w)
+ height = int(h)
+ # Maybe this is for an older PNG version.
+ elif (size >= 16) and data.startswith('\211PNG\r\n\032\n'):
+ w, h = struct.unpack(">LL", data[8:16])
+ width = int(w)
+ height = int(h)
+ return width, height
+
+class JPGFileSized(ImageFileSized):
+
+ interface.implements(ISized)
+ component.adapts(filetypes.IJPGFile)
+
+ def getImageSize(self):
+ data = self._image.data
+ data.seek(2)
+ size = self.bytes
+ height = -1
+ width = -1
+ b = data.read(1)
+ try:
+ w = -1
+ h = -1
+ while (b and ord(b) != 0xDA):
+ while (ord(b) != 0xFF): b = data.read(1)
+ while (ord(b) == 0xFF): b = data.read(1)
+ if (ord(b) >= 0xC0 and ord(b) <= 0xC3):
+ data.read(3)
+ h, w = struct.unpack(">HH", data.read(4))
+ break
+ else:
+ data.read(int(struct.unpack(">H", data.read(2))[0])-2)
+ b = data.read(1)
+ width = int(w)
+ height = int(h)
+ except struct.error:
+ pass
+ except ValueError:
+ pass
+ return width, height
Added: z3c.filetype/trunk/src/z3c/filetype/testdata/IMG_0504.JPG
===================================================================
(Binary files differ)
Property changes on: z3c.filetype/trunk/src/z3c/filetype/testdata/IMG_0504.JPG
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
More information about the Checkins
mailing list