kopia lustrzana https://github.com/wagtail/wagtail
Many improvements to smart cropping
rodzic
6f8b5faa06
commit
990cabef53
|
@ -44,17 +44,31 @@ class BaseImageBackend(object):
|
|||
|
||||
def crop_to_point(self, image, size, focal_point):
|
||||
crop_box = crop.crop_to_point(image.size, size, focal_point)
|
||||
|
||||
# Don't crop if we don't need to
|
||||
if crop_box.size != image.size:
|
||||
return self.crop(image, crop_box)
|
||||
else:
|
||||
return image
|
||||
image = self.crop(image, crop_box)
|
||||
|
||||
# If the focal points are too large, the cropping system may not
|
||||
# crop it fully, resize the image if this has happened:
|
||||
if crop_box.size != size:
|
||||
image = self.resize_to_fill(image, size)
|
||||
|
||||
return image
|
||||
|
||||
def crop_to_points(self, image, size, focal_points):
|
||||
crop_box = crop.crop_to_points(image.size, size, focal_points)
|
||||
|
||||
# Don't crop if we don't need to
|
||||
if crop_box.size != image.size:
|
||||
return self.crop(image, crop_box)
|
||||
else:
|
||||
return image
|
||||
image = self.crop(image, crop_box)
|
||||
|
||||
# If the focal points are too large, the cropping system may not
|
||||
# crop it fully, resize the image if this has happened:
|
||||
if crop_box.size != size:
|
||||
image = self.resize_to_fill(image, size)
|
||||
|
||||
return image
|
||||
|
||||
def smart_crop(self, image, size):
|
||||
image_mode, image_data = self.image_data_as_rgb(image)
|
||||
|
@ -161,7 +175,6 @@ class BaseImageBackend(object):
|
|||
resized_image = self.resize_to_min(image, size)
|
||||
return self.crop_to_centre(resized_image, size)
|
||||
|
||||
|
||||
def no_operation(self, image, param):
|
||||
"""Return the image unchanged"""
|
||||
return image
|
||||
|
|
|
@ -45,15 +45,49 @@ def crop_to_point(image_size, crop_size, focal_point):
|
|||
if not focal_point:
|
||||
focal_point = FocalPoint(original_width / 2, original_height / 2)
|
||||
|
||||
# Get size of focal point, add 15% extra to give some room around the edge
|
||||
focal_point_width = focal_point.width * 1.15
|
||||
focal_point_height = focal_point.height * 1.15
|
||||
|
||||
# Make sure that the crop size is no smaller than the focal point
|
||||
crop_width = max(crop_width, focal_point_width)
|
||||
crop_height = max(crop_height, focal_point_height)
|
||||
|
||||
# Make sure final dimensions do not exceed original dimensions
|
||||
final_width = min(original_width, crop_width)
|
||||
final_height = min(original_height, crop_height)
|
||||
|
||||
# Get UV for focal point
|
||||
focal_point_u = focal_point.x / original_width
|
||||
focal_point_v = focal_point.y / original_height
|
||||
|
||||
# Get crop box
|
||||
left = focal_point.x - final_width / 2
|
||||
top = focal_point.y - final_height / 2
|
||||
right = focal_point.x + final_width / 2
|
||||
bottom = focal_point.y + final_height / 2
|
||||
left = focal_point.x - focal_point_u * final_width
|
||||
top = focal_point.y - focal_point_v * final_height
|
||||
right = focal_point.x - focal_point_u * final_width + final_width
|
||||
bottom = focal_point.y - focal_point_v * final_height + final_height
|
||||
|
||||
# Make sure the entire focal point is in the crop box
|
||||
focal_point_left = focal_point.x - focal_point.width / 2
|
||||
focal_point_top = focal_point.y - focal_point.height / 2
|
||||
focal_point_right = focal_point.x + focal_point.width / 2
|
||||
focal_point_bottom = focal_point.y + focal_point.height / 2
|
||||
|
||||
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
|
||||
|
||||
# Don't allow the crop box to go over the image boundary
|
||||
if left < 0:
|
||||
|
@ -76,5 +110,9 @@ def crop_to_point(image_size, crop_size, focal_point):
|
|||
|
||||
|
||||
def crop_to_points(image_size, crop_size, focal_points):
|
||||
focal_point = combine_focal_points(focal_points)
|
||||
if len(focal_points) == 1:
|
||||
focal_point = focal_points[0]
|
||||
else:
|
||||
focal_point = combine_focal_points(focal_points)
|
||||
|
||||
return crop_to_point(image_size, crop_size, focal_point)
|
||||
|
|
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
|
@ -45,7 +45,7 @@ def detect_features(image_size, image_mode, image_data):
|
|||
|
||||
def detect_faces(image_size, image_mode, image_data):
|
||||
if opencv_available:
|
||||
cascade_filename = os.path.join(os.path.dirname(__file__), 'face_detection', 'haarcascade_frontalface_alt.xml')
|
||||
cascade_filename = os.path.join(os.path.dirname(__file__), 'face_detection', 'haarcascade_frontalface_alt2.xml')
|
||||
cascade = cv.Load(cascade_filename)
|
||||
image = get_cv_gray_image(image_size, image_mode, image_data)
|
||||
|
||||
|
|
|
@ -84,4 +84,16 @@ def combine_focal_points(focal_points):
|
|||
x = total_x / total_weight
|
||||
y = total_y / total_weight
|
||||
|
||||
return FocalPoint(x, y, weight=total_weight)
|
||||
min_x = min([point.x - point.width / 2 for point in focal_points])
|
||||
min_y = min([point.y - point.height / 2 for point in focal_points])
|
||||
max_x = max([point.x + point.width / 2 for point in focal_points])
|
||||
max_y = max([point.y + point.height / 2 for point in focal_points])
|
||||
|
||||
width = max_x - min_x
|
||||
height = max_y - min_y
|
||||
|
||||
return FocalPoint(x, y, width=width, height=height, weight=total_weight)
|
||||
|
||||
|
||||
def largest_point(focal_points):
|
||||
return sorted(focal_points, key=lambda point: point.weight, reverse=True)[0]
|
||||
|
|
Ładowanie…
Reference in New Issue