Пример #1
0
    def testConvertResizedSmallKeepRatio(self):
        # Verify that for an original red rectangular (vertically long image),
        # after conversion to a square size with blue background the output image
        # looks correct based on sampling color at several locations.
        orig_img = Image.new('RGBA', (50, 500), self.red_rgb)
        conversion_settings = convert.ImageConvertSettings(
            'png', 100, 100, bg_color_rgb=self.blue_rgb)

        # Final image should be a 10px wide by 100px tall rectangle centered
        # within the square, i.e., with center at pixel (49, 49) and borders of
        # 45 pixels on each side.
        image_converter = convert.ImageConverter(orig_img, conversion_settings)
        converted_img = image_converter.convert()

        # Just compare the RGB values, not opacity
        # Center should be red
        self.assertEqual(converted_img.getpixel((45, 45))[0:3], self.red_rgb)
        # Top Center should be red
        self.assertEqual(converted_img.getpixel((45, 0))[0:3], self.red_rgb)
        # Bottom Center should be red
        self.assertEqual(converted_img.getpixel((45, 99))[0:3], self.red_rgb)
        # Top left edge border should be blue background, then red rect.
        self.assertEqual(converted_img.getpixel((44, 0))[0:3], self.blue_rgb)
        self.assertEqual(converted_img.getpixel((45, 0))[0:3], self.red_rgb)
        # Bottom right edge border should be red, then blue background.
        self.assertEqual(converted_img.getpixel((54, 99))[0:3], self.red_rgb)
        self.assertEqual(converted_img.getpixel((55, 99))[0:3], self.blue_rgb)
Пример #2
0
    def testConvertTruncatedImage(self):
        # Should fail with a message that image is truncated.
        # To test image truncation, we actually need to write a file to disk.
        img_filepath = os.path.join(self.testdata_dir, 'test_img.png')

        try:
            orig_img = Image.new('RGBA', (500, 500), self.orange_rgb)
            orig_img.save(img_filepath)
            filesize = os.path.getsize(img_filepath)

            with open(img_filepath, 'r+') as img_on_disk:
                img_on_disk.truncate(filesize - 100)
            img_truncated = Image.open(img_filepath)

            image_converter = convert.ImageConverter(img_truncated,
                                                     self.conversion_settings)
            with self.assertRaises(IOError) as e:
                image_converter.convert()
            self.assertTrue('truncated' in str(e.exception).lower())
        except:
            raise
        finally:
            # Cleanup.
            if os.path.isfile(img_filepath):
                os.remove(img_filepath)
Пример #3
0
    def testConvertSmallerIgnoreRatioCropTopLeftNoAspectRatio(self):
        # Verify that we get the desired output image when cropping from top left.
        # In this case, the aspect ratio of the output image is different than
        # that of the orig image so cropping occurs.

        # Orig image is a 4 quadrant (200, 200) pixel image, with colors
        # (orange, red, green, yellow) starting from top left and going clockwise.
        orig_img = Image.new('RGBA', (200, 200), self.yellow_rgb)
        orig_img.paste(Image.new('RGBA', (100, 100), self.orange_rgb), (0, 0))
        orig_img.paste(Image.new('RGBA', (100, 100), self.red_rgb), (100, 0))
        orig_img.paste(Image.new('RGBA', (100, 100), self.green_rgb),
                       (100, 100))

        # Note that in this case, the aspect ratio has changed.
        conversion_settings = convert.ImageConvertSettings(
            'png',
            width=20,
            height=200,
            position=(0, 0),
            preserve_aspect_ratio=False)
        # Output image should be 20x200 that only contains the orange and yellow
        # sections since we crop from the left.
        image_converter = convert.ImageConverter(orig_img, conversion_settings)
        converted_img = image_converter.convert()

        # Top left of output image should be orange.
        self.assertEqual(converted_img.getpixel((0, 0))[0:3], self.orange_rgb)
        # Top right should be orange
        self.assertEqual(converted_img.getpixel((19, 0))[0:3], self.orange_rgb)
        # Bottom right should be yellow
        self.assertEqual(
            converted_img.getpixel((19, 199))[0:3], self.yellow_rgb)
        # Bottom left should be yellow
        self.assertEqual(
            converted_img.getpixel((0, 199))[0:3], self.yellow_rgb)
Пример #4
0
    def testConvertSmallerRightPosKeepRatio(self):
        # Same as above but we specify that the position remains in the right.
        # Verify that for an original red rectangular (vertically long image),
        # after conversion to a square size with blue background the output image
        # looks correct based on sampling color at several locations.
        orig_img = Image.new('RGBA', (50, 500), self.red_rgb)
        conversion_settings = convert.ImageConvertSettings(
            'png', 100, 100, position=(1, 0.5), bg_color_rgb=self.blue_rgb)

        # Final image should be a 10px wide by 100px tall rectangle flush with
        # the right edge of the output size. I.e., rectangle with center at pixel
        # (94, 49) and the blue background staring at x position 9.
        image_converter = convert.ImageConverter(orig_img, conversion_settings)
        converted_img = image_converter.convert()

        # Just compare the RGB values, not opacity
        # Center of image should be blue
        self.assertEqual(converted_img.getpixel((45, 45))[0:3], self.blue_rgb)
        # Top left corner should be blue background.
        self.assertEqual(converted_img.getpixel((0, 0))[0:3], self.blue_rgb)
        # Center of rectangle should be red
        self.assertEqual(converted_img.getpixel((94, 49))[0:3], self.red_rgb)
        # Bottom left edge of rectangle and adjacent background
        self.assertEqual(converted_img.getpixel((90, 99))[0:3], self.red_rgb)
        self.assertEqual(converted_img.getpixel((89, 99))[0:3], self.blue_rgb)
        # Top left edge of rectangle and adjacent background
        self.assertEqual(converted_img.getpixel((90, 0))[0:3], self.red_rgb)
        self.assertEqual(converted_img.getpixel((89, 0))[0:3], self.blue_rgb)
Пример #5
0
def get_and_convert_image(image_location, image_convert_settings,
                          allow_truncated_images=False, disk_cache=False,
                          request_timeout=60, http_max_retries=2):
  """Wrapper method that retrieves and converts one image.

  If run all in-memory (i.e., no disk spill), then returns PIL Image object.
  Otherwise returns path of disk-cached image.

  Args:
    image_location: Image path from the input list of locations.
    image_convert_settings: ImageConvertSettings object.
    allow_truncated_images: If True, PIL will be tolerant of truncated image
                            files and load/process them. Note that this isn't
                            supported on old versions on PIL, just pillow.
    disk_cache: Store intermediary image objects to disk. Not supported yet.
    request_timeout: Max secs for http requests before timeout.
    http_max_retries: Max number of attempts we will try to retrive http images
                      due to timeout errors.

  Returns:
    A tuple (Image object or None if fails, status message string). Status
    message string will be empty if success, or error message if failure.

  Exceptions handled:
    All exceptions for image retrieval are handled. Some notable ones are:
      - DecompressionBombError: Image is too large (>0.5G). See PIL
                                documentation for instructions on setting a
                                higher threshold.
    For image conversion, the following errors are handled:
      - IOError: error retrieving image file, or truncated image file.

  """
  if disk_cache:
    raise NotImplementedError()

  if allow_truncated_images:
    try:
      ImageFile.LOAD_TRUNCATED_IMAGES = True
    except AttributeError as e:
      logging.warning('Are you using PILLOW and not a very old version of PIL? '
                      'Unable to force load of truncated image files: %s', e)

  try:
    src_image = atlasmaker_io.get_image(image_location, request_timeout,
                                        http_max_retries=http_max_retries)
  except Exception as e:
    logging.error('Retrieval of file %s failed with error: %s',
                  image_location, e)
    return None, str(e)

  try:
    image_converter = convert.ImageConverter(src_image, image_convert_settings)
    logging.debug('Successfully converted image: %s' % image_location)
    return image_converter.convert(), ''
  except IOError as e:
    logging.error('Conversion of file %s failed with error: %s',
                  image_location, e)
    return None, str(e)
Пример #6
0
    def testConvertInputSizeSameAsOutput(self):
        # Verify that if input and output size are the same, things still work.
        orig_img = Image.new('RGBA', (100, 100))

        image_converter = convert.ImageConverter(orig_img,
                                                 self.conversion_settings)
        converted_img = image_converter.convert()

        self.assertEqual(converted_img.size,
                         (self.desired_width, self.desired_height))
Пример #7
0
    def testConvertImagePaddedLargerCorrectSize(self):
        # Input image is smaller than desired, but we just pad it to fit new size.
        conversion_settings = convert.ImageConvertSettings(
            'png',
            self.desired_width,
            self.desired_height,
            resize_if_larger=True)
        orig_img = Image.new('RGBA', (10, 10))

        image_converter = convert.ImageConverter(orig_img, conversion_settings)
        converted_img = image_converter.convert()

        self.assertEqual(converted_img.size,
                         (self.desired_width, self.desired_height))
Пример #8
0
    def testConvertResizedLargerKeepAspectRatio(self):
        conversion_settings = convert.ImageConvertSettings(
            'png',
            self.desired_width,
            self.desired_height,
            resize_if_larger=True,
            preserve_aspect_ratio=False)

        orig_img = Image.new('RGBA', (10, 10))

        image_converter = convert.ImageConverter(orig_img, conversion_settings)
        converted_img = image_converter.convert()

        self.assertEqual(converted_img.size,
                         (self.desired_width, self.desired_height))
Пример #9
0
    def testConvertSmallerIgnoreRatio(self):
        # Test resize image to smaller sprite without retaining aspect ratio.
        # Simply verifies correct size output.
        conversion_settings = convert.ImageConvertSettings(
            'png',
            self.desired_width,
            self.desired_height,
            preserve_aspect_ratio=False)
        orig_img = Image.new('RGBA', (1000, 500))

        image_converter = convert.ImageConverter(orig_img, conversion_settings)
        converted_img = image_converter.convert()

        self.assertEqual(converted_img.size,
                         (self.desired_width, self.desired_height))
Пример #10
0
    def testConvertSmallerKeepRatioHasCorrectSize(self):
        # Larger image is resized smaller, keeping aspect ratio.
        # This test simply verifies the size
        # TODO: delete and merge with following tests.
        conversion_settings = convert.ImageConvertSettings(
            'png',
            self.desired_width,
            self.desired_height,
            preserve_aspect_ratio=True)
        orig_img = Image.new('RGBA', (1000, 500))

        image_converter = convert.ImageConverter(orig_img, conversion_settings)
        converted_img = image_converter.convert()

        self.assertEqual(converted_img.size,
                         (self.desired_width, self.desired_height))
Пример #11
0
    def testConvertSmallerIgnoreRatioCropTopLeftSameAspectRatio(self):
        # Verify that we get the desired output image when cropping from left.
        # In this case, since the output image's aspect ratio is same as the input
        # image's aspect ratio, we're able to crop it correctly and keep the same
        # pattern.

        # Orig image is a 4 quadrant (200, 200) pixel image, with colors
        # (orange, red, green, yellow) starting from top left and going clockwise.
        orig_img = Image.new('RGBA', (200, 200), self.yellow_rgb)
        orig_img.paste(Image.new('RGBA', (100, 100), self.orange_rgb), (0, 0))
        orig_img.paste(Image.new('RGBA', (100, 100), self.red_rgb), (100, 0))
        orig_img.paste(Image.new('RGBA', (100, 100), self.green_rgb),
                       (100, 100))

        conversion_settings = convert.ImageConvertSettings(
            'png',
            self.desired_width,
            self.desired_height,
            position=(0, 0),
            preserve_aspect_ratio=False)

        # Output image should be 100x100 cropped from the center.
        image_converter = convert.ImageConverter(orig_img, conversion_settings)
        converted_img = image_converter.convert()

        # Top left of output image should be orange.
        self.assertEqual(converted_img.getpixel((0, 0))[0:3], self.orange_rgb)
        # Top right should be red
        self.assertEqual(converted_img.getpixel((99, 0))[0:3], self.red_rgb)
        # Bottom right should be green
        self.assertEqual(converted_img.getpixel((99, 99))[0:3], self.green_rgb)
        # Bottom left should be yellow
        self.assertEqual(converted_img.getpixel((0, 99))[0:3], self.yellow_rgb)
        # Center section should comprise the same set of colors clockwise.
        self.assertEqual(
            converted_img.getpixel((49, 49))[0:3], self.orange_rgb)
        self.assertEqual(converted_img.getpixel((50, 49))[0:3], self.red_rgb)
        self.assertEqual(converted_img.getpixel((50, 50))[0:3], self.green_rgb)
        self.assertEqual(
            converted_img.getpixel((49, 50))[0:3], self.yellow_rgb)
Пример #12
0
    def testConvertImageResizedLargerIgnoreRatio(self):
        # Verifies that output size and image (based on pixel samples) are correct.
        conversion_settings = convert.ImageConvertSettings(
            'png',
            self.desired_width,
            self.desired_height,
            bg_color_rgb=self.blue_rgb,
            resize_if_larger=True,
            preserve_aspect_ratio=False)
        orig_img = Image.new('RGBA', (20, 10), self.red_rgb)

        image_converter = convert.ImageConverter(orig_img, conversion_settings)
        converted_img = image_converter.convert()

        # Verify size.
        self.assertEqual(converted_img.size,
                         (self.desired_width, self.desired_height))
        # Image should be stretched to fit desired output size, so entire output
        # should be red. Verify center, and top left / bottom right edges.
        self.assertEqual(converted_img.getpixel((45, 45))[0:3], self.red_rgb)
        self.assertEqual(converted_img.getpixel((0, 0))[0:3], self.red_rgb)
        self.assertEqual(converted_img.getpixel((99, 99))[0:3], self.red_rgb)
Пример #13
0
    def testConvertResizedSmallDontKeepRatioCenterCrop(self):
        # Verify that we get the desired output image when cropping from center.

        # Orig image is a 4 quadrant (200, 200) pixel image, with colors
        # (orange, red, green, yellow) starting from top left and going clockwise.
        orig_img = Image.new('RGBA', (200, 200), self.yellow_rgb)
        orig_img.paste(Image.new('RGBA', (100, 100), self.orange_rgb), (0, 0))
        orig_img.paste(Image.new('RGBA', (100, 100), self.red_rgb), (100, 0))
        orig_img.paste(Image.new('RGBA', (100, 100), self.green_rgb),
                       (100, 100))

        conversion_settings = convert.ImageConvertSettings(
            'png',
            self.desired_width,
            self.desired_height,
            preserve_aspect_ratio=False)

        # Output image should be 100x100 cropped from the center.
        image_converter = convert.ImageConverter(orig_img, conversion_settings)
        converted_img = image_converter.convert()

        # Top left of output image should be orange.
        self.assertEqual(converted_img.getpixel((0, 0))[0:3], self.orange_rgb)
        # Top right should be red
        self.assertEqual(converted_img.getpixel((99, 0))[0:3], self.red_rgb)
        # Bottom right should be green
        self.assertEqual(converted_img.getpixel((99, 99))[0:3], self.green_rgb)
        # Bottom left should be yellow
        self.assertEqual(converted_img.getpixel((0, 99))[0:3], self.yellow_rgb)
        # Center section should comprise the same set of colors clockwise.
        self.assertEqual(
            converted_img.getpixel((49, 49))[0:3], self.orange_rgb)
        self.assertEqual(converted_img.getpixel((50, 49))[0:3], self.red_rgb)
        self.assertEqual(converted_img.getpixel((50, 50))[0:3], self.green_rgb)
        self.assertEqual(
            converted_img.getpixel((49, 50))[0:3], self.yellow_rgb)