import io
from PIL import Image
img = Image.open(fh, mode='r')
roi_img = img.crop(box)
img_byte_arr = io.BytesIO()
roi_img.save(img_byte_arr, format='PNG')
img_byte_arr = img_byte_arr.getvalue()
With this, I don't have to save the cropped image on my disk and I am able to retrieve the byte array from a PIL cropped image.
Answer from Evelyn Jeba on Stack Overflowimport io
from PIL import Image
img = Image.open(fh, mode='r')
roi_img = img.crop(box)
img_byte_arr = io.BytesIO()
roi_img.save(img_byte_arr, format='PNG')
img_byte_arr = img_byte_arr.getvalue()
With this, I don't have to save the cropped image on my disk and I am able to retrieve the byte array from a PIL cropped image.
This is my solution:
from PIL import Image
import io
def image_to_byte_array(image: Image) -> bytes:
# BytesIO is a file-like buffer stored in memory
imgByteArr = io.BytesIO()
# image.save expects a file-like as a argument
image.save(imgByteArr, format=image.format)
# Turn the BytesIO object back into a bytes object
imgByteArr = imgByteArr.getvalue()
return imgByteArr
My function accepts bytes to internaly opens them as a PIL.Image object. The function works as expected when bytes are passed to it. But I would like to write a couple of tests to it. So I need to generate images, turn them into bytes and pass them to my function so that it can turn it again back into an image.
Basically I wanna do something like this:
from PIL import Image from io import BytesIO orig = Image.new(mode='RGBA', size=(240, 60)) image_bytes = orig.tobytes() stream = BytesIO(image_bytes) new = Image.open(stream)
But what I don't understand is that it is not working and I get this Traceback:
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/Users/crane/PycharmProjects/my_project/venv/lib/python3.9/site-packages/PIL/Image.py", line 3030, in open
raise UnidentifiedImageError(
PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x104f86950>python - Open PIL image from byte file - Stack Overflow
PIL Image to bytes and saving it as jpg is not working
python - Convert PIL image to bytearray - Stack Overflow
python - PIL: Convert Bytearray to Image - Stack Overflow
The documentation for Image.open says that it can accept a file-like object, so you should be able to pass in a io.BytesIO object created from the bytes object containing the encoded image:
from PIL import Image
import io
image_data = ... # byte values of the image
image = Image.open(io.BytesIO(image_data))
image.show()
You can try this:
image = Image.frombytes('RGBA', (128,128), image_data, 'raw')
Source Code:def frombytes(mode, size, data, decoder_name="raw", *args): param mode: The image mode. param size: The image size. param data: A byte buffer containing raw data for the given mode. param decoder_name: What decoder to use.
I need to make a image to thumbnail and upload it to dropbox so I need to send it as Bytes, but it is not working So to recreate the problem
from PIL import Image
img = Image.open("test.jpg")
img.thumbnail((128,128), Image.ANTIALIAS)
bytes = img.tobytes()
#These bytes are send to the dropbox
f = open("128.jpg", "wb")
f.write(bytes)
f.close()
And I can't open the image.
What am I missing here?
Thanks in Advance
from io import BytesIO
from PIL import Image
with BytesIO() as output:
with Image.open(path_to_image) as img:
img.save(output, 'BMP')
data = output.getvalue()
.. warning::
This method returns the raw image data from the internal storage. For compressed image data (e.g. PNG, JPEG) use :meth:
~.save, with a BytesIO parameter for in-memory data.
This is the warning in the tobytes method. So we can use the save method with a BytesIO parameter to get a compressed byte array.
import io
byteIO = io.BytesIO()
image.save(byteIO, format='PNG')
byteArr = byteIO.getvalue()
Try:
import os
print os.stat('somefile.ext').st_size
If you already have the image on the filesystem:
import os
# Get the size in bytes.
os.path.getsize("path_to_file.jpg")
If, however, you want to get the saved size of an image that is in memory and has not been saved to the filesystem:
from io import BytesIO
img_file = BytesIO()
# quality='keep' is a Pillow setting that maintains the quantization of the image.
# Not having the same quantization can result in different sizes between the in-
# memory image and the file size on disk.
image.save(img_file, "png", quality = "keep")
image_file_size = img_file.tell()
NOTE: if you use a different quality setting for each method you can end up with a smaller size in one or the other.
This method will avoid multiple reads of the image data as with StringIO. Note, however, that it will use more RAM. Everything is a tradeoff. :-)
Edit: I just saw this comment from the OP:
finally, the problem is from the beginnig, if someone will upload a picture that have 1 giga (forged one) he'll kill the server before PIL will do its stuff, so i must block the request before it finishs!
This is a very different question, and is probably best accomplished at the web server. For nginx, you can add this to your configuration:
http {
# or whatever size you want as your limit
client_max_body_size 100m;
}