Round dimensions for images when scaling.

Add hook for validating image operations.
pull/5257/head
Adrian Brunyate 2019-02-11 13:01:30 -05:00 zatwierdzone przez LB Johnston
rodzic b7f53ef276
commit d3b8bcb689
4 zmienionych plików z 39 dodań i 3 usunięć

Wyświetl plik

@ -9,6 +9,7 @@ Changelog
* Rearranged SCSS folder structure to the client folder and split them approximately according to ITCSS. (Naomi Morduch Toubman, Jonny Scholes, Janneke Janssen, Hugo van den Berg)
* Fix: ModelAdmin no longer fails when filtering over a foreign key relation (Jason Dilworth, Matt Westcott)
* Fix: The Wagtail version number is now visible within the Settings menu (Kevin Howbrook)
* Fix: Scaling images now rounds values to an integer so that images render without errors (Adrian Brunyate)
2.5 (24.04.2019)

Wyświetl plik

@ -23,6 +23,7 @@ Bug fixes
* ModelAdmin no longer fails when filtering over a foreign key relation (Jason Dilworth, Matt Westcott)
* The Wagtail version number is now visible within the Settings menu (Kevin Howbrook)
* Scaling images now rounds values to an integer so that images render without errors (Adrian Brunyate)
Upgrade considerations

Wyświetl plik

@ -225,8 +225,8 @@ class ScaleOperation(Operation):
image_width, image_height = willow.get_size()
scale = self.percent / 100
width = float(image_width * scale)
height = float(image_height * scale)
width = int(image_width * scale)
height = int(image_height * scale)
return willow.resize((width, height))

Wyświetl plik

@ -23,11 +23,20 @@ class WillowOperationRecorder:
def __getattr__(self, attr):
def operation(*args, **kwargs):
self.validate_operation(attr, args, kwargs)
self.ran_operations.append((attr, args, kwargs))
return self
return operation
def validate_operation(self, operation, args, kwargs):
"""Check if the requested operation is sane and raise an exception if not."""
# The Willow docs say resize must take integral dimensions.
if operation == "resize":
x, y = args[0]
if x != int(x) or y != int(y):
raise ValueError
def get_size(self):
size = self.start_size
@ -46,6 +55,7 @@ class ImageOperationTestCase(TestCase):
filter_spec_tests = []
filter_spec_error_tests = []
run_tests = []
norun_tests = []
@classmethod
def make_filter_spec_test(cls, filter_spec, expected_output):
@ -88,6 +98,25 @@ class ImageOperationTestCase(TestCase):
test_run.__name__ = str('test_run_%s' % filter_spec)
return test_run
@classmethod
def make_norun_test(cls, filter_spec, image_kwargs):
def test_norun(self):
image = Image(**image_kwargs)
# Make operation
operation = self.operation_class(*filter_spec.split('-'))
# Make operation recorder
operation_recorder = WillowOperationRecorder((image.width, image.height))
# Attempt (and hopefully fail) to run
with self.assertRaises(ValueError):
operation.run(operation_recorder, image, {})
test_norun.__name__ = str('test_norun_%s' % filter_spec)
return test_norun
@classmethod
def setup_test_methods(cls):
if cls.operation_class is None:
@ -108,6 +137,11 @@ class ImageOperationTestCase(TestCase):
run_test = cls.make_run_test(*args)
setattr(cls, run_test.__name__, run_test)
# Runtime error tests
for args in cls.norun_tests:
norun_test = cls.make_norun_test(*args)
setattr(cls, norun_test.__name__, norun_test)
class TestDoNothingOperation(ImageOperationTestCase):
operation_class = image_operations.DoNothingOperation
@ -388,7 +422,7 @@ class TestScaleOperation(ImageOperationTestCase):
]),
# Rounded usage of scale
('scale-83.0322', dict(width=1000, height=500), [
('resize', ((1000 * 0.830322, 500 * 0.830322), ), {}),
('resize', ((int(1000 * 0.830322), int(500 * 0.830322)), ), {}),
]),
]