Use rect class in fill operation

This commit is contained in:
Karl Hobley 2015-07-27 11:58:08 +01:00
parent c9a5d1242e
commit 79b6170631
2 changed files with 78 additions and 36 deletions

View file

@ -1,9 +1,9 @@
from __future__ import division
import inspect
import math
from wagtail.wagtailimages.exceptions import InvalidFilterSpecError
from wagtail.wagtailimages.rect import Rect
class Operation(object):
@ -118,48 +118,17 @@ class FillOperation(Operation):
crop_y = fp_y - (fp_v - 0.5) * crop_height
# Convert crop box into rect
left = crop_x - crop_width / 2
top = crop_y - crop_height / 2
right = crop_x + crop_width / 2
bottom = crop_y + crop_height / 2
rect = Rect.from_point(crop_x, crop_y, crop_width, crop_height)
# Make sure the entire focal point is in the crop box
if focal_point is not None:
if left > focal_point.left:
right -= left - focal_point.left
left = focal_point.left
if top > focal_point.top:
bottom -= top - focal_point.top
top = focal_point.top
if right < focal_point.right:
left += focal_point.right - right
right = focal_point.right
if bottom < focal_point.bottom:
top += focal_point.bottom - bottom
bottom = focal_point.bottom
rect = rect.move_to_cover(focal_point)
# Don't allow the crop box to go over the image boundary
if left < 0:
right -= left
left = 0
if top < 0:
bottom -= top
top = 0
if right > image_width:
left -= right - image_width
right = image_width
if bottom > image_height:
top -= bottom - image_height
bottom = image_height
rect = rect.move_to_clamp(Rect(0, 0, image_width, image_height))
# Crop!
willow.crop((math.floor(left), math.floor(top), math.ceil(right), math.ceil(bottom)))
willow.crop(rect.round())
# Get scale for resizing
# The scale should be the same for both the horizontal and

View file

@ -1,5 +1,7 @@
from __future__ import division
import math
class Vector(object):
def __init__(self, x, y):
@ -86,6 +88,77 @@ class Rect(object):
# Included for backwards compatibility
return self.left, self.top, self.right, self.bottom
def clone(self):
return type(self)(self.left, self.top, self.right, self.bottom)
def round(self):
"""
Returns a new rect with all attributes rounded to integers
"""
clone = self.clone()
# Round down left and top
clone.left = int(math.floor(clone.left))
clone.top = int(math.floor(clone.top))
# Round up right and bottom
clone.right = int(math.ceil(clone.right))
clone.bottom = int(math.ceil(clone.bottom))
return clone
def move_to_clamp(self, other):
"""
Moves this rect so it is completely covered by the rect in "other" and
returns a new Rect instance.
"""
other = Rect(*other)
clone = self.clone()
if clone.left < other.left:
clone.right -= clone.left - other.left
clone.left = other.left
if clone.top < other.top:
clone.bottom -= clone.top - other.top
clone.top = other.top
if clone.right > other.right:
clone.left -= clone.right - other.right
clone.right = other.right
if clone.bottom > other.bottom:
clone.top -= clone.bottom - other.bottom
clone.bottom = other.bottom
return clone
def move_to_cover(self, other):
"""
Moves this rect so it completely covers the rect specified in the
"other" parameter and returns a new Rect instance.
"""
other = Rect(*other)
clone = self.clone()
if clone.left > other.left:
clone.right -= clone.left - other.left
clone.left = other.left
if clone.top > other.top:
clone.bottom -= clone.top - other.top
clone.top = other.top
if clone.right < other.right:
clone.left += other.right - clone.right
clone.right = other.right
if clone.bottom < other.bottom:
clone.top += other.bottom - clone.bottom
clone.bottom = other.bottom
return clone
def __iter__(self):
return iter((self.left, self.top, self.right, self.bottom))