def test_aspect_ratio_approximate(self):
     self.assertEqual(
         aspect_ratio_approximate((640, 480)),
         Decimal('1.33')
     )
     self.assertEqual(
         aspect_ratio_approximate((4, 3)),
         Decimal('1.33')
     )
def scales_extractor(widget, data):
    scales = attr_value('scales', widget, data)
    if not scales or not data.extracted or not data.extracted.get('image'):
        return data.extracted
    image = data.extracted['image']
    scaled_images = dict()
    image_appr = aspect_ratio_approximate(image.size)
    for name, size in scales.items():
        scale_appr = aspect_ratio_approximate(size)
        if same_aspect_ratio(size, image.size):
            image_size = size
        # scale x
        if image_appr > scale_appr:
            image_size = scale_size(image.size, (size[0], None))
        # scale y
        if image_appr < scale_appr:
            image_size = scale_size(image.size, (None, size[1]))
        scaled_images[name] = image.resize(image_size, Image.ANTIALIAS)
    data.extracted['scales'] = scaled_images
    return data.extracted
 def test_extract_from_image_cropping_foundations(self):
     buffer = StringIO(self.dummy_png)
     image = PIL.Image.open(buffer)
     buffer.seek(0)
     data = buffer.read()
     # save cropped image to testing folder for manual inspection
     left, top, width, height = 7, 3, 30, 40
     cropped = image.crop((left, top, width, height))
     path = pkg_resources.resource_filename(
         'yafowil.widget.image', 'testing/cropped.png')
     cropped.save(path, quality=100)
     # fitting logic
     self.assertTrue(same_aspect_ratio((300, 200), (600, 400)))
     # scale X down
     self.assertEqual(scale_size((100, 50), (75, None)), (75, 37))
     # scale X up
     self.assertEqual(scale_size((100, 50), (150, None)), (150, 75))
     # scale Y down
     self.assertEqual(scale_size((100, 50), (None, 25)), (50, 25))
     # scale Y up
     self.assertEqual(scale_size((100, 50), (None, 100)), (200, 100))
     # scale x
     size_from = (60, 40)
     self.assertEqual(aspect_ratio_approximate(size_from), Decimal('1.50'))
     size_to = (50, 25)
     self.assertEqual(aspect_ratio_approximate(size_to), Decimal('2.00'))
     self.assertTrue(
         aspect_ratio_approximate(size_from) <
         aspect_ratio_approximate(size_to)
     )
     scaled = scale_size(size_from, (size_to[0], None))
     self.assertEqual(scaled, (50, 33))
     offset_y = (scaled[1] - size_to[1]) / 2
     self.assertEqual(offset_y, 4)
     # scale y
     size_from = (60, 40)
     self.assertEqual(aspect_ratio_approximate(size_from), Decimal('1.50'))
     size_to = (50, 35)
     self.assertEqual(aspect_ratio_approximate(size_to), Decimal('1.43'))
     self.assertTrue(
         aspect_ratio_approximate(size_from) >
         aspect_ratio_approximate(size_to)
     )
     scaled = scale_size(size_from, (None, size_to[1]))
     self.assertEqual(scaled, (52, 35))
     offset_x = (scaled[0] - size_to[0]) / 2
     self.assertEqual(offset_x, 1)
def crop_extractor(widget, data):
    """XXX:
    - support cropping definitions as request parameters.
        left, top, width, height (for use with JS cropping plugin)
    - alignment
        tl (top left), tr (top right), bl (bottom left),
        br (bottom right), ce (center), rc (right center),
        lc (left center), tc (top center), bc (bottom center)
    """
    crop = attr_value('crop', widget, data)
    if not crop or not data.extracted or not data.extracted.get('image'):
        return data.extracted
    size = crop['size']
    offset = crop.get('offset', (0, 0))
    fitting = crop.get('fitting', False)
    image = data.extracted['image']
    image_appr = aspect_ratio_approximate(image.size)
    crop_appr = aspect_ratio_approximate(size)
    if fitting:
        if same_aspect_ratio(size, image.size):
            image = image.resize(size, Image.ANTIALIAS)
            offset = (0, 0)
        # scale x
        if image_appr < crop_appr:
            image_size = scale_size(image.size, (size[0], None))
            image = image.resize(image_size, Image.ANTIALIAS)
            offset = (0, (image_size[1] - size[1]) / 2)
        # scale y
        if image_appr > crop_appr:
            image_size = scale_size(image.size, (None, size[1]))
            image = image.resize(image_size, Image.ANTIALIAS)
            offset = ((image_size[0] - size[0]) / 2, 0)
    image = image.crop(
        (offset[0], offset[1], size[0] + offset[0], size[1] + offset[1]))
    data.extracted['cropped'] = image
    return data.extracted