Question

I am am getting an image from email attachment and will never touch disk. Image will be placed into a StringIO container and processed by PIL. How do I get the file size in bytes?

image_file = StringIO('image from email')
im = Image.open(image_file)
Was it helpful?

Solution

Use StringIO's .tell() method by seeking to the end of the file:

>>> from StringIO import StringIO
>>> s = StringIO("foobar")
>>> s.tell()
0
>>> s.seek(0, 2)
>>> s.tell()
6

In your case:

image_file = StringIO('image from email')
image_file.seek(0, 2)  # Seek to the end
bytes = image_file.tell()  # Get no. of bytes
image_file.seek(0)  # Seek to the start
im = Image.open(image_file)

OTHER TIPS

Suppose you have:

>>> s = StringIO("cat\u2014jack")
>>> s.seek(0, os.SEEK_END)
>>> print(s.tell())
8

This however is incorrect. \u2014 is an emdash character - a single character but it is 3 bytes long.

>>> len("\u2014")
1
>>> len("\u2014".encode("utf-8"))
3

StringIO may not use utf-8 for storage either. It used to use UCS-2 or UCS-4 but since pep 393 may be using utf-8 or some other encoding depending on the circumstance.

What ultimately matters is the binary representation you ultimately go with. If you're encoding text, and you'll eventually write the file out encoded as utf-8 then you have to encode the value in it's entirety to know how many bytes it will take up. This is because as a variable-length encoding, utf-8 characters may require multiple bytes to encode.

You could do something like:

>>> s = StringIO("cat\u2014jack")
>>> size = len(s.getvalue().encode('utf-8'))
10
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top