Commit f164aeb2 authored by Serge S. Koval's avatar Serge S. Koval

Fixed image re-encoding when uploading images. Thumbnails will keep...

Fixed image re-encoding when uploading images. Thumbnails will keep transparency for transparent GIF/PNG files.
parent f2e83df3
...@@ -118,6 +118,7 @@ class FileUploadField(fields.TextField): ...@@ -118,6 +118,7 @@ class FileUploadField(fields.TextField):
def __init__(self, label=None, validators=None, def __init__(self, label=None, validators=None,
base_path=None, relative_path=None, base_path=None, relative_path=None,
namegen=None, allowed_extensions=None, namegen=None, allowed_extensions=None,
permission=0o666,
**kwargs): **kwargs):
""" """
Constructor. Constructor.
...@@ -155,6 +156,8 @@ class FileUploadField(fields.TextField): ...@@ -155,6 +156,8 @@ class FileUploadField(fields.TextField):
self.namegen = namegen or namegen_filename self.namegen = namegen or namegen_filename
self.allowed_extensions = allowed_extensions self.allowed_extensions = allowed_extensions
self.permission = permission
self._should_delete = False self._should_delete = False
super(FileUploadField, self).__init__(label, validators, **kwargs) super(FileUploadField, self).__init__(label, validators, **kwargs)
...@@ -227,7 +230,7 @@ class FileUploadField(fields.TextField): ...@@ -227,7 +230,7 @@ class FileUploadField(fields.TextField):
def _save_file(self, data, filename): def _save_file(self, data, filename):
path = self._get_path(filename) path = self._get_path(filename)
if not op.exists(op.dirname(path)): if not op.exists(op.dirname(path)):
os.makedirs(os.path.dirname(path), 0o666) os.makedirs(os.path.dirname(path), self.permission)
data.save(path) data.save(path)
...@@ -255,6 +258,7 @@ class ImageUploadField(FileUploadField): ...@@ -255,6 +258,7 @@ class ImageUploadField(FileUploadField):
namegen=None, allowed_extensions=None, namegen=None, allowed_extensions=None,
max_size=None, max_size=None,
thumbgen=None, thumbnail_size=None, thumbgen=None, thumbnail_size=None,
permission=0o666,
url_relative_path=None, endpoint='static', url_relative_path=None, endpoint='static',
**kwargs): **kwargs):
""" """
...@@ -338,6 +342,7 @@ class ImageUploadField(FileUploadField): ...@@ -338,6 +342,7 @@ class ImageUploadField(FileUploadField):
relative_path=relative_path, relative_path=relative_path,
namegen=namegen, namegen=namegen,
allowed_extensions=allowed_extensions, allowed_extensions=allowed_extensions,
permission=permission,
**kwargs) **kwargs)
def pre_validate(self, form): def pre_validate(self, form):
...@@ -364,29 +369,35 @@ class ImageUploadField(FileUploadField): ...@@ -364,29 +369,35 @@ class ImageUploadField(FileUploadField):
# Saving # Saving
def _save_file(self, data, filename): def _save_file(self, data, filename):
path = self._get_path(filename) path = self._get_path(filename)
if not op.exists(op.dirname(path)): if not op.exists(op.dirname(path)):
os.makedirs(os.path.dirname(path), 0o666) os.makedirs(os.path.dirname(path), self.permission)
if self.image and self.max_size: # Figure out format
filename, format = self._get_save_format(filename, self.image) filename, format = self._get_save_format(filename, self.image)
self._save_image(self._resize(self.image, self.max_size), if self.image and (self.image.format != format or self.max_size):
self._get_path(filename), if self.max_size:
format) image = self._resize(self.image, self.max_size)
else:
image = self.image
self._save_image(image, self._get_path(filename), format)
else: else:
data.seek(0) data.seek(0)
data.save(path) data.save(path)
self._save_thumbnail(data, filename) self._save_thumbnail(data, filename, format)
return filename return filename
def _save_thumbnail(self, data, filename): def _save_thumbnail(self, data, filename, format):
if self.image and self.thumbnail_size: if self.image and self.thumbnail_size:
path = self._get_path(self.thumbnail_fn(filename)) path = self._get_path(self.thumbnail_fn(filename))
self._save_image(self._resize(self.image, self.thumbnail_size), self._save_image(self._resize(self.image, self.thumbnail_size),
path) path,
format)
def _resize(self, image, size): def _resize(self, image, size):
(width, height, force) = size (width, height, force) = size
...@@ -402,12 +413,14 @@ class ImageUploadField(FileUploadField): ...@@ -402,12 +413,14 @@ class ImageUploadField(FileUploadField):
return image return image
def _save_image(self, image, path, format='JPEG'): def _save_image(self, image, path, format='JPEG'):
image = image.convert('RGB') if image.mode not in ('RGB', 'RGBA'):
image = image.convert('RGBA')
with open(path, 'wb') as fp: with open(path, 'wb') as fp:
image.save(fp, format) image.save(fp, format)
def _get_save_format(self, filename, image): def _get_save_format(self, filename, image):
if not image.format in self.keep_image_formats: if image.format not in self.keep_image_formats:
name, ext = op.splitext(filename) name, ext = op.splitext(filename)
filename = '%s.jpg' % name filename = '%s.jpg' % name
return filename, 'JPEG' return filename, 'JPEG'
...@@ -428,4 +441,4 @@ def thumbgen_filename(filename): ...@@ -428,4 +441,4 @@ def thumbgen_filename(filename):
Generate thumbnail name from filename. Generate thumbnail name from filename.
""" """
name, ext = op.splitext(filename) name, ext = op.splitext(filename)
return '%s_thumb.jpg' % name return '%s_thumb%s' % (name, ext)
...@@ -133,7 +133,7 @@ def test_image_upload_field(): ...@@ -133,7 +133,7 @@ def test_image_upload_field():
eq_(dummy.upload, 'test1.png') eq_(dummy.upload, 'test1.png')
ok_(op.exists(op.join(path, 'test1.png'))) ok_(op.exists(op.join(path, 'test1.png')))
ok_(op.exists(op.join(path, 'test1_thumb.jpg'))) ok_(op.exists(op.join(path, 'test1_thumb.png')))
# Check replace # Check replace
with open(filename, 'rb') as fp: with open(filename, 'rb') as fp:
...@@ -146,7 +146,7 @@ def test_image_upload_field(): ...@@ -146,7 +146,7 @@ def test_image_upload_field():
eq_(dummy.upload, 'test2.png') eq_(dummy.upload, 'test2.png')
ok_(op.exists(op.join(path, 'test2.png'))) ok_(op.exists(op.join(path, 'test2.png')))
ok_(op.exists(op.join(path, 'test2_thumb.jpg'))) ok_(op.exists(op.join(path, 'test2_thumb.png')))
ok_(not op.exists(op.join(path, 'test1.png'))) ok_(not op.exists(op.join(path, 'test1.png')))
ok_(not op.exists(op.join(path, 'test1_thumb.jpg'))) ok_(not op.exists(op.join(path, 'test1_thumb.jpg')))
...@@ -161,7 +161,7 @@ def test_image_upload_field(): ...@@ -161,7 +161,7 @@ def test_image_upload_field():
eq_(dummy.upload, None) eq_(dummy.upload, None)
ok_(not op.exists(op.join(path, 'test2.png'))) ok_(not op.exists(op.join(path, 'test2.png')))
ok_(not op.exists(op.join(path, 'test2_thumb.jpg'))) ok_(not op.exists(op.join(path, 'test2_thumb.png')))
# Check upload no-resize # Check upload no-resize
with open(filename, 'rb') as fp: with open(filename, 'rb') as fp:
...@@ -174,7 +174,7 @@ def test_image_upload_field(): ...@@ -174,7 +174,7 @@ def test_image_upload_field():
eq_(dummy.upload, 'test1.png') eq_(dummy.upload, 'test1.png')
ok_(op.exists(op.join(path, 'test1.png'))) ok_(op.exists(op.join(path, 'test1.png')))
ok_(not op.exists(op.join(path, 'test1_thumb.jpg'))) ok_(not op.exists(op.join(path, 'test1_thumb.png')))
# Check upload, auto-resize # Check upload, auto-resize
filename = op.join(op.dirname(__file__), 'data', 'copyleft.png') filename = op.join(op.dirname(__file__), 'data', 'copyleft.png')
......
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