Pillow Black&White Image is saved as a blacksquare

47 Views Asked by At

I get an image from PySide6 Canvas.

Initial Image

I can show it in the browser properly. But while saving this one, I get the black square.

Saved Image

While converting the image into a NumPy array I get correct figures in the array.

Large screenshot of Numpy array

I can't understand what is going wrong while saving image.

I expected to save the image properly but I can't find a way to.

the class code

import numpy as np from PIL import Image, ImageOps from numpy.typing import NDArray from typing import Tuple, Union

THRESHOLD = 100 FINAL_SIZE = 28

class Utils:

@classmethod
def get_formatted_image(cls, pil_im: Image, as_ndarray=True) -> Union[Image.Image, NDArray]:
    """
    Converts an image of the number into NumPy array
    """
    pil_im = cls._get_cropped_image(cls._get_gscale_image(pil_im))
    pil_im = pil_im.resize((FINAL_SIZE, FINAL_SIZE), resample=1)
    pil_im = cls._get_gscale_image(pil_im, inverse=False)
    return np.array(pil_im) if as_ndarray else pil_im

@staticmethod
def _get_gscale_image(img: Image, inverse=True) -> Image:
    """
    Converts image into a black-white one
    """
    converted_image = img.convert('L')
    return ImageOps.invert(converted_image) if inverse else converted_image

@classmethod
def _get_cropped_image(cls, img: Image) -> Image:
    """
    Crops the image (converts the image into a squared one)
    """
    img_np = np.array(img)
    boundaries = cls._get_boundaries(img_np)
    img_np = img_np[boundaries[0]: boundaries[2], boundaries[1]: boundaries[3]]
    return Image.fromarray(img_np)

@staticmethod
def _get_boundaries(np_img: NDArray, inverted_image=True) -> Tuple:
    """
    Gets boundaries of the image
    """
    x = {k: v for k, v in enumerate(np_img.sum(axis=1) / np_img.shape[1])}
    y = {k: v for k, v in enumerate(np_img.sum(axis=0) / np_img.shape[0])}

    if inverted_image:
        x = list(filter(lambda z: z[1] > 0, x.items()))
        y = list(filter(lambda z: z[1] > 0, y.items()))
    else:
        x = list(filter(lambda z: z[1] < 255, x.items()))
        y = list(filter(lambda z: z[1] < 255, y.items()))

    return min(x)[0], min(y)[0], max(x)[0], max(y)[0]

Anything else is given above. There is nothing else I can add.

processed_own_image.show()

gives expected result, but

processes_own_image.save('temp.png', 'PNG') gives a black square

0

There are 0 best solutions below