def compress(img_path: str, b: int, out_path: str) -> str:
    """
    Compresses an image into a format with bits to
    represent each channel. Saves the image and returns
    the path to compressed output image specified by the out_path.

    Parameters:
    ----------
    img_path: str (file path to a .png image)
    b: int in [1, 8]
    out_path: str (file path to the compressed png image)

    Returns:
    -------
    compressed_img : str (file path to the image with each channel
                    compressed to b bits, same as out_path)

    Examples:
    -------
    >>> imageCompress.compress("..//image.png", b = 5, "..//compressed_image.png")
    >>> "..//compressed_image.png"
    """

    if type(img_path) != str:
        raise TypeError(
            "Input image path type not correct, make sure you are passing a string!"
        )
    if type(out_path) != str:
        raise TypeError(
            "Output path type not correct, make sure you are passing a string!"
        )
    if type(b) != int:
        raise TypeError("b should be a positive integer <= 8!")
    if b <= 0:
        raise ValueError(
            "b should be a positive integer greater than 0 and less than 9!")
    if b > 8:
        raise ValueError("b should be a positive integer <= 8!")

    min_size_img = compression(
        img_path, 1,
        os.path.join((os.path.dirname(os.path.abspath(img_path))), "1.png"))
    desired_size_img = compression(
        img_path, b,
        os.path.join((os.path.dirname(os.path.abspath(img_path))), "2.png"))

    if image_size(min_size_img) > image_size(img_path):
        os.remove(min_size_img)
        os.remove(desired_size_img)
        raise Exception("The image is already compressed")

    elif image_size(desired_size_img) > image_size(img_path):
        os.remove(min_size_img)
        os.remove(desired_size_img)
        raise Exception("Choose a smaller b to compress the image.")

    else:
        os.remove(min_size_img)
        os.remove(desired_size_img)
        return compression(img_path, b, out_path)
Example #2
0
def compress(img_path, b, out_path):
    """
    Compresses an image into a format with bits to
    represent each channel.

    Parameters:
    ----------
    img_path: str (file path to a .png image)
    b: int in [1, 8]
    out_path: str (file path to the compressed png image)

    Returns:
    -------
    compressed_img : str (file path to the image with each channel
                    compressed to b bits, same as out_path)
    """

    if type(img_path) != str or type(out_path) != str:
        raise TypeError(
            "Image path not correct, make sure you are passing a string!")

    if type(b) != int:
        raise TypeError("b should be a positive integer <= 8!")

    if b <= 0 or b > 8:
        raise ValueError("b should be a positive integer <= 8!")

    min_size_img = compression(
        img_path, 1,
        os.path.join((os.path.dirname(os.path.abspath(img_path))), "1.png"))
    desired_size_img = compression(
        img_path, b,
        os.path.join((os.path.dirname(os.path.abspath(img_path))), "2.png"))

    if image_size(min_size_img) > image_size(img_path):
        os.remove(min_size_img)
        os.remove(desired_size_img)
        raise Exception("The image is already compressed")

    elif image_size(desired_size_img) > image_size(img_path):
        os.remove(min_size_img)
        os.remove(desired_size_img)
        raise Exception("Choose a smaller b to compress the image.")

    else:
        os.remove(min_size_img)
        os.remove(desired_size_img)
        return compression(img_path, b, out_path)
 def test_size_type(self):
     '''
     Function to test that a TypeError is raised when invalid type is passed in
     as image
     '''
     with pytest.raises(TypeError):
         image_size(imread(img_path))
     with pytest.raises(TypeError):
         image_size(True)
     with pytest.raises(TypeError):
         image_size(123)
     with pytest.raises(TypeError):
         image_size(12.2)
    def test_compress_size(self):
        '''
        Function to test that the size of the compressed image
        is correct
        '''
        compressed_img = compress(img_path, 3, outpath)
        assert image_size(compressed_img) < 7 / 8 * image_size(img_path)

        compressed_img = compress(img_path, 1, outpath)
        assert image_size(compressed_img) < 5 / 8 * image_size(img_path)

        compressed_img = compress(img_path, 6, outpath)
        assert image_size(compressed_img) <= 8 / 8 * image_size(img_path)

        compressed_img = compress(img_path, 8, outpath)
        assert image_size(compressed_img) <= image_size(img_path)
 def test_size_output(self):
     '''
     Function to test that correct size is returned
     '''
     assert image_size(img_path) <= 1.1 * imread(img_path).nbytes