Commit aec500f8 authored by Cédric Le Ninivin's avatar Cédric Le Ninivin

Add crop option to image parameters

Conflicts:
	product/ERP5OOo/tests/testDms.py
parent 882a2668
...@@ -294,20 +294,23 @@ class Image(TextConvertableMixin, File, OFSImage): ...@@ -294,20 +294,23 @@ class Image(TextConvertableMixin, File, OFSImage):
# pixel (number of it = 128x128) # pixel (number of it = 128x128)
kw['image_size'] = image_size kw['image_size'] = image_size
display = kw.pop('display', None) display = kw.pop('display', None)
mime, image = self._makeDisplayPhoto(**kw) crop = kw.pop('crop', None)
mime, image = self._makeDisplayPhoto(crop=crop, **kw)
image_data = image.data image_data = image.data
# as image will always be requested through a display not by passing exact # as image will always be requested through a display not by passing exact
# pixels we need to restore this way in cache # pixels we need to restore this way in cache
if display is not None: if display is not None:
# only set if we have a real value # only set if we have a real value
kw['display'] = display kw['display'] = display
if crop:
kw['crop'] = crop
image_size = kw.pop('image_size', None) image_size = kw.pop('image_size', None)
self.setConversion(image_data, mime, **kw) self.setConversion(image_data, mime, **kw)
return mime, image_data return mime, image_data
# Display # Display
security.declareProtected(Permissions.View, 'index_html') security.declareProtected(Permissions.View, 'index_html')
@fill_args_from_request('display', 'quality', 'resolution', 'frame') @fill_args_from_request('display', 'quality', 'resolution', 'frame', 'crop')
def index_html(self, REQUEST, *args, **kw): def index_html(self, REQUEST, *args, **kw):
"""Return the image data.""" """Return the image data."""
self._upgradeImage() self._upgradeImage()
...@@ -317,11 +320,16 @@ class Image(TextConvertableMixin, File, OFSImage): ...@@ -317,11 +320,16 @@ class Image(TextConvertableMixin, File, OFSImage):
# Photo processing # Photo processing
# #
def _resize(self, quality, width, height, format, resolution, frame): def _resize(self, quality, width, height, format, resolution, frame, crop=False):
"""Resize and resample photo.""" """Resize and resample photo."""
parameter_list = ['convert', '-colorspace', 'sRGB', '-depth', '8', parameter_list = ['convert', '-colorspace', 'sRGB', '-depth', '8']
'-quality', str(quality), if crop :
'-geometry', '%sx%s' % (width, height)] parameter_list += '-thumbnail', '%sx%s^' % (width, height),\
'-gravity', 'center',\
'-extent','%sx%s' % (width, height)
else:
parameter_list += '-geometry', '%sx%s' % (width, height)
parameter_list += '-quality', str(quality)
if format not in VALID_TRANSPARENT_IMAGE_FORMAT_LIST: if format not in VALID_TRANSPARENT_IMAGE_FORMAT_LIST:
# ImageMagick way to remove transparent that works with multiple # ImageMagick way to remove transparent that works with multiple
# images. http://www.imagemagick.org/Usage/masking/#remove # images. http://www.imagemagick.org/Usage/masking/#remove
...@@ -357,18 +365,22 @@ class Image(TextConvertableMixin, File, OFSImage): ...@@ -357,18 +365,22 @@ class Image(TextConvertableMixin, File, OFSImage):
return StringIO(image) return StringIO(image)
raise ConversionError('Image conversion failed (%s).' % err) raise ConversionError('Image conversion failed (%s).' % err)
def _getDisplayData(self, format, quality, resolution, frame, image_size): def _getDisplayData(self, format, quality, resolution, frame, image_size, crop):
"""Return raw photo data for given display.""" """Return raw photo data for given display."""
if crop:
width, height = image_size
else:
width, height = self._getAspectRatioSize(*image_size) width, height = self._getAspectRatioSize(*image_size)
if ((width, height) == image_size or (width, height) == (0, 0))\ if ((width, height) == image_size or (width, height) == (0, 0))\
and quality == self.getDefaultImageQuality(format) and resolution is None and frame is None\ and quality == self.getDefaultImageQuality(format) and resolution is None and frame is None\
and not format: and not format:
# No resizing, no conversion, return raw image # No resizing, no conversion, return raw image
return self.getData() return self.getData()
return self._resize(quality, width, height, format, resolution, frame) return self._resize(quality, width, height, format, resolution, frame, crop)
def _makeDisplayPhoto(self, format=None, quality=_MARKER, def _makeDisplayPhoto(self, format=None, quality=_MARKER,
resolution=None, frame=None, image_size=None): resolution=None, frame=None, image_size=None,
crop=False):
"""Create given display.""" """Create given display."""
if quality is _MARKER: if quality is _MARKER:
quality = self.getDefaultImageQuality(format) quality = self.getDefaultImageQuality(format)
...@@ -377,7 +389,8 @@ class Image(TextConvertableMixin, File, OFSImage): ...@@ -377,7 +389,8 @@ class Image(TextConvertableMixin, File, OFSImage):
id = '%s_%s_%s.%s'% (base, width, height, ext,) id = '%s_%s_%s.%s'% (base, width, height, ext,)
image = OFSImage(id, self.getTitle(), image = OFSImage(id, self.getTitle(),
self._getDisplayData(format, quality, resolution, self._getDisplayData(format, quality, resolution,
frame, image_size)) frame, image_size,
crop))
return image.content_type, aq_base(image) return image.content_type, aq_base(image)
def _getAspectRatioSize(self, width, height): def _getAspectRatioSize(self, width, height):
......
...@@ -76,6 +76,7 @@ import re ...@@ -76,6 +76,7 @@ import re
from AccessControl import Unauthorized from AccessControl import Unauthorized
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
from DateTime import DateTime from DateTime import DateTime
from ZTUtils import make_query
QUIET = 0 QUIET = 0
...@@ -243,7 +244,7 @@ class TestDocument(TestDocumentMixin): ...@@ -243,7 +244,7 @@ class TestDocument(TestDocumentMixin):
def getURLSizeList(self, uri, **kw): def getURLSizeList(self, uri, **kw):
# __ac=RVJQNVR5cGVUZXN0Q2FzZTo%3D is encoded ERP5TypeTestCase with empty password # __ac=RVJQNVR5cGVUZXN0Q2FzZTo%3D is encoded ERP5TypeTestCase with empty password
url = '%s?%s&__ac=%s' %(uri, urllib.urlencode(kw), 'RVJQNVR5cGVUZXN0Q2FzZTo%3D') url = '%s?%s&__ac=%s' %(uri, make_query(kw), 'RVJQNVR5cGVUZXN0Q2FzZTo%3D')
format=kw.get('format', 'jpeg') format=kw.get('format', 'jpeg')
infile = urllib.urlopen(url) infile = urllib.urlopen(url)
# save as file with proper incl. format filename (for some reasons PIL uses this info) # save as file with proper incl. format filename (for some reasons PIL uses this info)
...@@ -2252,6 +2253,12 @@ return 1 ...@@ -2252,6 +2253,12 @@ return 1
# Image # Image
image_document_image_size, image_document_file_size = self.getURLSizeList(image_document_url, **convert_kw) image_document_image_size, image_document_file_size = self.getURLSizeList(image_document_url, **convert_kw)
self.assertTrue(max(preffered_size_for_display) - max(image_document_image_size) <= max_tollerance_px) self.assertTrue(max(preffered_size_for_display) - max(image_document_image_size) <= max_tollerance_px)
self.assertTrue(abs(min(preffered_size_for_display) - min(image_document_image_size)) >= max_tollerance_px)
cropped_image_document_image_size, cropped_image_document_file_size = \
self.getURLSizeList(image_document_url, crop = 1, **convert_kw)
self.assertEqual(max(preffered_size_for_display), max(cropped_image_document_image_size))
self.assertEqual(min(preffered_size_for_display), min(cropped_image_document_image_size))
# Web Page # Web Page
web_page_image_size, web_page_file_size = self.getURLSizeList(web_page_document_url, **convert_kw) web_page_image_size, web_page_file_size = self.getURLSizeList(web_page_document_url, **convert_kw)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment