def test_compression_results_in_identical_files(self):
        with python_utils.open_file(
            os.path.join(
                feconf.TESTS_DATA_DIR, 'compressed_image.jpg'),
            'rb', encoding=None) as f:
            correct_compressed_image = f.read()
        correct_height, correct_width = (
            image_services.get_image_dimensions(correct_compressed_image))
        compressed_image = (
            image_services.compress_image(self.jpeg_raw_image, 0.5))

        # In order to make sure the images are the same, the function needs to
        # open and save the image specifically using PIL since the "golden
        # image" (image that we compare the compressed image to) is saved using
        # PIL. This applies a slight quality change that won't appear unless we
        # save it using PIL.
        temp_image = Image.open(io.BytesIO(compressed_image))
        image_format = temp_image.format
        with io.BytesIO() as output:
            temp_image.save(output, format=image_format)
            compressed_image_content = output.getvalue()
        height, width = image_services.get_image_dimensions(
            compressed_image_content)
        self.assertEqual(correct_height, height)
        self.assertEqual(correct_width, width)

        image1 = Image.open(io.BytesIO(correct_compressed_image)).convert('RGB')
        image2 = Image.open(io.BytesIO(compressed_image_content)).convert('RGB')
        diff = ImageChops.difference(image1, image2)

        # Function diff.getbbox() returns a bounding box on all islands or
        # regions of non-zero pixels. In other words, if we have a bounding
        # box, there will be areas that are not 0 in the difference meaning
        # that the 2 images are not equal.
        self.assertFalse(diff.getbbox())
 def test_compress_image_returns_correct_dimensions(self):
     compressed_image = (
         image_services.compress_image(self.jpeg_raw_image, 0.5))
     height, width = (
         image_services.get_image_dimensions(compressed_image))
     self.assertEqual(self.TEST_IMAGE_HEIGHT * 0.5, height)
     self.assertEqual(self.TEST_IMAGE_WIDTH * 0.5, width)
Exemple #3
0
    def test_compress_image_on_prod_mode_with_small_image_size(self):
        with python_utils.open_file(
            os.path.join(feconf.TESTS_DATA_DIR, 'img.png'), mode='rb',
            encoding=None) as f:
            original_image_content = f.read()

        with self.swap(constants, 'DEV_MODE', False):
            fs = fs_domain.AbstractFileSystem(
                fs_domain.GcsFileSystem(
                    feconf.ENTITY_TYPE_EXPLORATION, self.EXPLORATION_ID))

            self.assertFalse(fs.isfile('image/%s' % self.FILENAME))
            self.assertFalse(
                fs.isfile('image/%s' % self.COMPRESSED_IMAGE_FILENAME))
            self.assertFalse(fs.isfile('image/%s' % self.MICRO_IMAGE_FILENAME))

            fs_services.save_original_and_compressed_versions_of_image(
                self.FILENAME, 'exploration', self.EXPLORATION_ID,
                original_image_content, 'image', True)

            self.assertTrue(fs.isfile('image/%s' % self.FILENAME))
            self.assertTrue(
                fs.isfile('image/%s' % self.COMPRESSED_IMAGE_FILENAME))
            self.assertTrue(fs.isfile('image/%s' % self.MICRO_IMAGE_FILENAME))

            original_image_content = fs.get(
                'image/%s' % self.FILENAME)
            compressed_image_content = fs.get(
                'image/%s' % self.COMPRESSED_IMAGE_FILENAME)
            micro_image_content = fs.get(
                'image/%s' % self.MICRO_IMAGE_FILENAME)

            self.assertEqual(
                image_services.get_image_dimensions(
                    original_image_content),
                (32, 32))
            self.assertEqual(
                image_services.get_image_dimensions(
                    compressed_image_content),
                (25, 25))
            self.assertEqual(
                image_services.get_image_dimensions(
                    micro_image_content),
                (22, 22))
    def map(model):  # pylint: disable=too-many-return-statements
        if model.deleted:
            yield ('SUCCESS - DELETED', model.username)
            return

        if model.username is None:
            yield ('SUCCESS - NOT REGISTERED', model.username)
            return

        if model.profile_picture_data_url is None:
            yield ('FAILURE - MISSING PROFILE PICTURE', model.username)
            return

        try:
            profile_picture_binary = utils.convert_png_data_url_to_binary(
                model.profile_picture_data_url)
        except Exception:
            yield ('FAILURE - INVALID PROFILE PICTURE DATA URL', model.username)
            return

        if imghdr.what(None, h=profile_picture_binary) != 'png':
            yield ('FAILURE - PROFILE PICTURE NOT PNG', model.username)
            return

        try:
            # Load the image to retrieve dimensions for later verification.
            height, width = image_services.get_image_dimensions(
                profile_picture_binary)
        except Exception:
            yield ('FAILURE - CANNOT LOAD PROFILE PICTURE', model.username)
            return

        if (
                height != user_services.GRAVATAR_SIZE_PX or
                width != user_services.GRAVATAR_SIZE_PX
        ):
            yield (
                'FAILURE - PROFILE PICTURE NON STANDARD DIMENSIONS - %s,%s' % (
                    height, width
                ),
                model.username
            )
            return

        yield ('SUCCESS', model.username)
def get_filename_with_dimensions(old_filename, exp_id):
    """Gets the filename with dimensions of the image file in it.

    Args:
        old_filename: str. Name of the file whose dimensions need to be
            calculated.
        exp_id: str. Exploration id.

    Returns:
        str. The new filename of the image file.
    """
    file_system_class = fs_services.get_entity_file_system_class()
    fs = fs_domain.AbstractFileSystem(
        file_system_class(feconf.ENTITY_TYPE_EXPLORATION, exp_id))
    filepath = 'image/%s' % old_filename
    try:
        content = fs.get(filepath.encode('utf-8'))
        height, width = image_services.get_image_dimensions(content)
    except IOError:
        height = 120
        width = 120
    new_filename = regenerate_image_filename_using_dimensions(
        old_filename, height, width)
    return new_filename
 def test_image_dimensions_are_output_correctly(self):
     height, width = (image_services.get_image_dimensions(
         self.jpeg_raw_image))
     self.assertEqual(self.TEST_IMAGE_HEIGHT, height)
     self.assertEqual(self.TEST_IMAGE_WIDTH, width)