Home > other >  Image is corrupted after PIL's tobytes() method
Image is corrupted after PIL's tobytes() method

Time:05-26

I want to upload an image to a Google Bucket, however I want to reduce the size of the image before uploading. When I don't call the self._resize_image method the image gets successfully uploaded without any problems. However, when I call the resize method it works until the image.tobytes() method. After the image.tobytes() method is called the image seems to get corrupted. I tried to debug manually and Googling about the tobytes method, but haven't found anything so far. Do you have an idea what causes the image to get corrupted or is there an alternative to scale the image?

def _resize_image(self, image: bytes, base_with: int = 300) -> bytes:
    stream = BytesIO(image)
    image = Image.open(stream).convert("RGBA")
    width_percentage = base_with / float(image.size[0])
    height_size = int(float(image.size[1]) * float(width_percentage))
    image = image.resize((base_with, height_size), Image.ANTIALIAS)
    # if I do image.show() here the picture is still displayed correctly.
    return image.tobytes()  # after this line the picture is getting uploaded, but can't be read by Google anymore.

def upload_image_to_bucket(self, image: bytes, bucket_folder: str, compress: bool = True) -> str:
    if compress:
        # if I don't call this method the picture get's uploaded correctly.
        image = self._resize_image(image=image)
    file_name = f"{UUIDService().create_uuid(length=40)}.jpeg"
    bucket = self._client.storage.bucket()
    blob = bucket.blob(f"{bucket_folder}/{file_name}")
    blob.upload_from_string(data=image, content_type="image/jpeg")
    return file_name

CodePudding user response:

From Pillow's documentation on tobytes:

This method returns the raw image data from the internal storage. For compressed image data (e.g. PNG, JPEG) use save(), with a BytesIO parameter for in-memory data.

So the tobytes() method returns Pillow's internal representation of the image, presumably to be restored with frombytes(). If you want to save the image as JPEG, use the save() method as suggested by the documentation:

output = BytesIO()
image.save(output, format="jpeg")
... # do something with `output`

CodePudding user response:

This is because the tobytes() function gives raw uncompressed bytes. You would have use PIL's save function to save into a buffer and then upload that.

output = io.BytesIO()
img.save(output, format='JPEG')

CodePudding user response:

It may be the Image.ANTIALIAS function; try leaving that field blank.

  • Related