Esempio n. 1
0
def save_original_and_compressed_versions_of_image(filename, entity_type,
                                                   entity_id,
                                                   original_image_content,
                                                   filename_prefix,
                                                   image_is_compressible):
    """Saves the three versions of the image file.

    Args:
        filename: str. The name of the image file.
        entity_type: str. The type of the entity.
        entity_id: str. The id of the entity.
        original_image_content: str. The content of the original image.
        filename_prefix: str. The string to prefix to the filename.
        image_is_compressible: bool. Whether the image can be compressed or
            not.
    """
    filepath = '%s/%s' % (filename_prefix, filename)

    filename_wo_filetype = filename[:filename.rfind('.')]
    filetype = filename[filename.rfind('.') + 1:]

    compressed_image_filename = '%s_compressed.%s' % (filename_wo_filetype,
                                                      filetype)
    compressed_image_filepath = '%s/%s' % (filename_prefix,
                                           compressed_image_filename)

    micro_image_filename = '%s_micro.%s' % (filename_wo_filetype, filetype)
    micro_image_filepath = '%s/%s' % (filename_prefix, micro_image_filename)

    file_system_class = get_entity_file_system_class()
    fs = fs_domain.AbstractFileSystem(file_system_class(
        entity_type, entity_id))

    if image_is_compressible:
        compressed_image_content = image_services.compress_image(
            original_image_content, 0.8)
        micro_image_content = image_services.compress_image(
            original_image_content, 0.7)
    else:
        compressed_image_content = original_image_content
        micro_image_content = original_image_content

    mimetype = ('image/svg+xml' if filetype == 'svg' else 'image/%s' %
                filetype)
    # Because in case of CreateVersionsOfImageJob, the original image is
    # already there. Also, even if the compressed, micro versions for some
    # image exists, then this would prevent from creating another copy of
    # the same.
    if not fs.isfile(filepath):
        fs.commit(filepath, original_image_content, mimetype=mimetype)

    if not fs.isfile(compressed_image_filepath):
        fs.commit(compressed_image_filepath,
                  compressed_image_content,
                  mimetype=mimetype)

    if not fs.isfile(micro_image_filepath):
        fs.commit(micro_image_filepath, micro_image_content, mimetype=mimetype)
    def test_compression_results_in_correct_format(self):
        compressed_image = (image_services.compress_image(
            self.jpeg_raw_image, 0.7))
        pil_image = Image.open(io.BytesIO(compressed_image))
        self.assertEqual(pil_image.format, 'JPEG')

        compressed_image = (image_services.compress_image(
            self.png_raw_image, 0.7))
        pil_image = Image.open(io.BytesIO(compressed_image))
        self.assertEqual(pil_image.format, 'PNG')
Esempio n. 3
0
 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)
Esempio n. 4
0
    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())
Esempio n. 5
0
    def test_invalid_scaling_factor_triggers_value_error(self):
        value_exception = self.assertRaisesRegexp(
            ValueError,
            r'Scaling factor should be in the interval \(0, 1], received 1.1.')
        with value_exception:
            image_services.compress_image(self.jpeg_raw_image, 1.1)

        value_exception = self.assertRaisesRegexp(
            ValueError,
            r'Scaling factor should be in the interval \(0, 1], received 0.')
        with value_exception:
            image_services.compress_image(self.jpeg_raw_image, 0)

        value_exception = self.assertRaisesRegexp(
            ValueError,
            r'Scaling factor should be in the interval \(0, 1], received -1.')
        with value_exception:
            image_services.compress_image(self.jpeg_raw_image, -1)
Esempio n. 6
0
    def test_invalid_scaling_factor_triggers_value_error(self) -> None:
        value_exception = self.assertRaisesRegex(# type: ignore[no-untyped-call]
            ValueError,
            re.escape(
                'Scaling factor should be in the interval (0, 1], '
                'received 1.100000.'))
        with value_exception:
            image_services.compress_image(self.jpeg_raw_image, 1.1)

        value_exception = self.assertRaisesRegex(# type: ignore[no-untyped-call]
            ValueError,
            re.escape(
                'Scaling factor should be in the interval (0, 1], '
                'received 0.000000.'))
        with value_exception:
            image_services.compress_image(self.jpeg_raw_image, 0)

        value_exception = self.assertRaisesRegex(# type: ignore[no-untyped-call]
            ValueError,
            re.escape(
                'Scaling factor should be in the interval (0, 1], '
                'received -1.000000.'))
        with value_exception:
            image_services.compress_image(self.jpeg_raw_image, -1)