Pillow identifies, reads, and writes PNG files containing 1 , L , LA , I , P , RGB or RGBA data.
To load the image, we simply import the image module from the pillow and call the Image. open(), passing the image filename. Instead of calling the Pillow module, we will call the PIL module as to make it backward compatible with an older module called Python Imaging Library (PIL).
You can use the BytesIO
class to get a wrapper around strings that behaves like a file. The BytesIO
object provides the same interface as a file, but saves the contents just in memory:
import io
with io.BytesIO() as output:
image.save(output, format="GIF")
contents = output.getvalue()
You have to explicitly specify the output format with the format
parameter, otherwise PIL will raise an error when trying to automatically detect it.
If you loaded the image from a file it has a format
parameter that contains the original file format, so in this case you can use format=image.format
.
In old Python 2 versions before introduction of the io
module you would have used the StringIO
module instead.
For Python3 it is required to use BytesIO:
from io import BytesIO
from PIL import Image, ImageDraw
image = Image.new("RGB", (300, 50))
draw = ImageDraw.Draw(image)
draw.text((0, 0), "This text is drawn on image")
byte_io = BytesIO()
image.save(byte_io, 'PNG')
Read more: http://fadeit.dk/blog/post/python3-flask-pil-in-memory-image
sth's solution didn't work for me
because in ...
Imaging/PIL/Image.pyc line 1423 -> raise KeyError(ext) # unknown extension
It was trying to detect the format from the extension in the filename , which doesn't exist in StringIO case
You can bypass the format detection by setting the format yourself in a parameter
import StringIO
output = StringIO.StringIO()
format = 'PNG' # or 'JPEG' or whatever you want
image.save(output, format)
contents = output.getvalue()
output.close()
save()
can take a file-like object as well as a path, so you can use an in-memory buffer like a StringIO
:
buf = StringIO.StringIO()
im.save(buf, format='JPEG')
jpeg = buf.getvalue()
With modern (as of mid-2017 Python 3.5 and Pillow 4.0):
StringIO no longer seems to work as it used to. The BytesIO class is the proper way to handle this. Pillow's save function expects a string as the first argument, and surprisingly doesn't see StringIO as such. The following is similar to older StringIO solutions, but with BytesIO in its place.
from io import BytesIO
from PIL import Image
image = Image.open("a_file.png")
faux_file = BytesIO()
image.save(faux_file, 'png')
When you say "I'd like to have number of such images stored in dictionary", it's not clear if this is an in-memory structure or not.
You don't need to do any of this to meek an image in memory. Just keep the image
object in your dictionary.
If you're going to write your dictionary to a file, you might want to look at im.tostring()
method and the Image.fromstring()
function
http://effbot.org/imagingbook/image.htm
im.tostring() => string
Returns a string containing pixel data, using the standard "raw" encoder.
Image.fromstring(mode, size, data) => image
Creates an image memory from pixel data in a string, using the standard "raw" decoder.
The "format" (.jpeg, .png, etc.) only matters on disk when you are exchanging the files. If you're not exchanging files, format doesn't matter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With