Example #1
0
    def get_suggested_focal_point(self):
        with self.get_willow_image() as willow:
            faces = willow.detect_faces()

            if faces:
                # Create a bounding box around all faces
                left = min(face[0] for face in faces)
                top = min(face[1] for face in faces)
                right = max(face[2] for face in faces)
                bottom = max(face[3] for face in faces)
                focal_point = Rect(left, top, right, bottom)
            else:
                features = willow.detect_features()
                if features:
                    # Create a bounding box around all features
                    left = min(feature[0] for feature in features)
                    top = min(feature[1] for feature in features)
                    right = max(feature[0] for feature in features)
                    bottom = max(feature[1] for feature in features)
                    focal_point = Rect(left, top, right, bottom)
                else:
                    return None

        # Add 20% to width and height and give it a minimum size
        x, y = focal_point.centroid
        width, height = focal_point.size

        width *= 1.20
        height *= 1.20

        width = max(width, 100)
        height = max(height, 100)

        return Rect.from_point(x, y, width, height)
Example #2
0
 def test_getitem(self):
     rect = Rect(100, 150, 200, 250)
     self.assertEqual(rect[0], 100)
     self.assertEqual(rect[1], 150)
     self.assertEqual(rect[2], 200)
     self.assertEqual(rect[3], 250)
     self.assertRaises(IndexError, rect.__getitem__, 4)
Example #3
0
 def test_centroid(self):
     rect = Rect(100, 150, 200, 350)
     self.assertIsInstance(rect.centroid, Vector)
     self.assertEqual(rect.centroid, (150, 250))
     self.assertEqual(rect.x, 150)
     self.assertEqual(rect.y, 250)
     self.assertEqual(rect.centroid_x, 150)
     self.assertEqual(rect.centroid_y, 250)
Example #4
0
    def test_get_focal_point(self):
        self.assertEqual(self.image.get_focal_point(), None)

        # Add a focal point to the image
        self.image.focal_point_x = 100
        self.image.focal_point_y = 200
        self.image.focal_point_width = 50
        self.image.focal_point_height = 20

        # Get it
        self.assertEqual(self.image.get_focal_point(), Rect(75, 190, 125, 210))
Example #5
0
 def get_focal_point(self):
     if self.focal_point_x is not None and \
        self.focal_point_y is not None and \
        self.focal_point_width is not None and \
        self.focal_point_height is not None:
         return Rect.from_point(
             self.focal_point_x,
             self.focal_point_y,
             self.focal_point_width,
             self.focal_point_height,
         )
Example #6
0
    def test_fill_filter_with_focal_point(self):
        image = Image.objects.create(
            title="Test image",
            file=get_test_image_file(filename='test_rf3.png'),
        )
        image.set_focal_point(Rect(100, 100, 200, 200))
        image.save()

        rendition = image.get_rendition('fill-100x100')

        self.assertEqual(rendition.file.name,
                         'images/test_rf3.15ee4958.fill-100x100.png')
Example #7
0
    def test_filter_with_pipe_gets_dotted(self):
        image = Image.objects.create(
            title="Test image",
            file=get_test_image_file(filename='test_rf4.png'),
        )
        image.set_focal_point(Rect(100, 100, 200, 200))
        image.save()

        rendition = image.get_rendition('fill-200x200|height-150')

        self.assertEqual(
            rendition.file.name,
            'images/test_rf4.15ee4958.fill-200x200.height-150.png')
Example #8
0
    def test_set_focal_point(self):
        self.assertEqual(self.image.focal_point_x, None)
        self.assertEqual(self.image.focal_point_y, None)
        self.assertEqual(self.image.focal_point_width, None)
        self.assertEqual(self.image.focal_point_height, None)

        self.image.set_focal_point(Rect(100, 150, 200, 350))

        self.assertEqual(self.image.focal_point_x, 150)
        self.assertEqual(self.image.focal_point_y, 250)
        self.assertEqual(self.image.focal_point_width, 100)
        self.assertEqual(self.image.focal_point_height, 200)

        self.image.set_focal_point(None)

        self.assertEqual(self.image.focal_point_x, None)
        self.assertEqual(self.image.focal_point_y, None)
        self.assertEqual(self.image.focal_point_width, None)
        self.assertEqual(self.image.focal_point_height, None)
    def run(self, willow, image, env):
        image_width, image_height = willow.get_size()
        focal_point = image.get_focal_point()

        # Get crop aspect ratio
        crop_aspect_ratio = self.width / self.height

        # Get crop max
        crop_max_scale = min(image_width, image_height * crop_aspect_ratio)
        crop_max_width = crop_max_scale
        crop_max_height = crop_max_scale / crop_aspect_ratio

        # Initialise crop width and height to max
        crop_width = crop_max_width
        crop_height = crop_max_height

        # Use crop closeness to zoom in
        if focal_point is not None:
            # Get crop min
            crop_min_scale = max(focal_point.width,
                                 focal_point.height * crop_aspect_ratio)
            crop_min_width = crop_min_scale
            crop_min_height = crop_min_scale / crop_aspect_ratio

            # Sometimes, the focal point may be bigger than the image...
            if not crop_min_scale >= crop_max_scale:
                # Calculate max crop closeness to prevent upscaling
                max_crop_closeness = max(
                    1 - (self.width - crop_min_width) /
                    (crop_max_width - crop_min_width),
                    1 - (self.height - crop_min_height) /
                    (crop_max_height - crop_min_height))

                # Apply max crop closeness
                crop_closeness = min(self.crop_closeness, max_crop_closeness)

                if 1 >= crop_closeness >= 0:
                    # Get crop width and height
                    crop_width = crop_max_width + (
                        crop_min_width - crop_max_width) * crop_closeness
                    crop_height = crop_max_height + (
                        crop_min_height - crop_max_height) * crop_closeness

        # Find focal point UV
        if focal_point is not None:
            fp_x, fp_y = focal_point.centroid
        else:
            # Fall back to positioning in the centre
            fp_x = image_width / 2
            fp_y = image_height / 2

        fp_u = fp_x / image_width
        fp_v = fp_y / image_height

        # Position crop box based on focal point UV
        crop_x = fp_x - (fp_u - 0.5) * crop_width
        crop_y = fp_y - (fp_v - 0.5) * crop_height

        # Convert crop box into rect
        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:
            rect = rect.move_to_cover(focal_point)

        # Don't allow the crop box to go over the image boundary
        rect = rect.move_to_clamp(Rect(0, 0, image_width, image_height))

        # Crop!
        willow = willow.crop(rect.round())

        # Get scale for resizing
        # The scale should be the same for both the horizontal and
        # vertical axes
        aftercrop_width, aftercrop_height = willow.get_size()
        scale = self.width / aftercrop_width

        # Only resize if the image is too big
        if scale < 1.0:
            # Resize!
            willow = willow.resize((self.width, self.height))

        return willow
Example #10
0
 def test_get_rect(self):
     self.assertTrue(self.image.get_rect(), Rect(0, 0, 640, 480))
Example #11
0
 def test_from_point(self):
     rect = Rect.from_point(100, 200, 50, 20)
     self.assertEqual(rect, Rect(75, 190, 125, 210))
Example #12
0
 def test_repr(self):
     rect = Rect(100, 150, 200, 250)
     self.assertEqual(repr(rect),
                      "Rect(left: 100, top: 150, right: 200, bottom: 250)")
Example #13
0
 def test_set_centroid_with_vector(self):
     rect = Rect(100, 150, 200, 350)
     rect.centroid = Vector(500, 500)
     self.assertEqual(rect, (450, 400, 550, 600))
Example #14
0
 def test_set_size_with_vector(self):
     rect = Rect(100, 150, 200, 350)
     rect.size = Vector(200, 400)
     self.assertEqual(rect, (50, 50, 250, 450))
Example #15
0
 def test_size(self):
     rect = Rect(100, 150, 200, 350)
     self.assertIsInstance(rect.size, Vector)
     self.assertEqual(rect.size, (100, 200))
     self.assertEqual(rect.width, 100)
     self.assertEqual(rect.height, 200)
Example #16
0
 def test_as_tuple(self):
     rect = Rect(100, 150, 200, 250)
     self.assertEqual(rect.as_tuple(), (100, 150, 200, 250))
Example #17
0
 def get_rect(self):
     return Rect(0, 0, self.width, self.height)
Example #18
0
 def test_equality(self):
     self.assertEqual(Rect(100, 150, 200, 250), Rect(100, 150, 200, 250))
     self.assertNotEqual(Rect(100, 150, 200, 250), Rect(10, 15, 20, 25))
Example #19
0
 def test_init(self):
     rect = Rect(100, 150, 200, 250)
     self.assertEqual(rect.left, 100)
     self.assertEqual(rect.top, 150)
     self.assertEqual(rect.right, 200)
     self.assertEqual(rect.bottom, 250)