summaryrefslogtreecommitdiff
path: root/postgresqleu/util/fields.py
diff options
context:
space:
mode:
Diffstat (limited to 'postgresqleu/util/fields.py')
-rw-r--r--postgresqleu/util/fields.py41
1 files changed, 33 insertions, 8 deletions
diff --git a/postgresqleu/util/fields.py b/postgresqleu/util/fields.py
index ae41061a..88b381b0 100644
--- a/postgresqleu/util/fields.py
+++ b/postgresqleu/util/fields.py
@@ -2,7 +2,9 @@ from django.db import models
from django.core.exceptions import ValidationError
from .forms import ImageBinaryFormField, PdfBinaryFormField
-from PIL import ImageFile
+import io
+
+from PIL import Image, ImageFile
from postgresqleu.util.magic import magicdb
@@ -19,7 +21,8 @@ class ImageBinaryField(models.Field):
empty_values = [None, b'']
def __init__(self, max_length, *args, **kwargs):
- self.max_resolution = kwargs.pop('max_resolution', None)
+ self.resolution = kwargs.pop('resolution', None)
+ self.auto_scale = kwargs.pop('auto_scale', False)
super(ImageBinaryField, self).__init__(*args, **kwargs)
self.max_length = max_length
@@ -65,12 +68,34 @@ class ImageBinaryField(models.Field):
except Exception as e:
raise ValidationError("Could not parse image: %s" % e)
- if img.format.upper() != 'JPEG':
- raise ValidationError("Only JPEG files are allowed")
-
- if self.max_resolution:
- if img.size[0] > self.max_resolution[0] or img.size[1] > self.max_resolution[1]:
- raise ValidationError("Maximum image size is {}x{}".format(*self.max_resolution))
+ if img.format.upper() not in ('JPEG', 'PNG'):
+ raise ValidationError("Only JPEG or PNG files are allowed")
+
+ if self.resolution:
+ if img.size[0] != self.resolution[0] or img.size[1] != self.resolution[1]:
+ if self.auto_scale:
+ scale = min(
+ float(self.resolution[0]) / float(img.size[0]),
+ float(self.resolution[1]) / float(img.size[1]),
+ )
+ newimg = img.resize(
+ (int(img.size[0] * scale), int(img.size[1] * scale)),
+ Image.BICUBIC,
+ )
+ saver = io.BytesIO()
+ if newimg.size[0] != newimg.size[1]:
+ # This is not a square, so we have to roll it again
+ centeredimg = Image.new('RGBA', self.resolution)
+ centeredimg.paste(newimg, (
+ (self.resolution[0] - newimg.size[0]) // 2,
+ (self.resolution[1] - newimg.size[1]) // 2,
+ ))
+ centeredimg.save(saver, format='PNG')
+ else:
+ newimg.save(saver, format="PNG")
+ value = saver.getvalue()
+ else:
+ raise ValidationError("Image size must be {}x{}".format(*self.resolution))
return value