9

How do I create a pickleable file from a PIL Image object such that you could save those images as a single pickle file then maybe upload to another computer such as a server running PIL and unpickle it there?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
vijaym123
  • 323
  • 1
  • 3
  • 8

2 Answers2

17

You can convert the Image object into data then you can pickle it:

image = {
    'pixels': im.tostring(),
    'size': im.size,
    'mode': im.mode,
}

And back to an Image:

im = Image.fromstring(image['mode'], image['size'], image['pixels'])

NOTE: As astex mentioned, if you're using Pillow (which is recommended instead of PIL), the tostring() method is deprecated for tobytes(). Likewise with fromstring() for frombytes().

gak
  • 32,061
  • 28
  • 119
  • 154
  • 1
    `Image.tostring()` is now deprecated in `Pillow` in favor of `Image.tobytes()`. For the sake of posterity, it may be better to change the above (or at least leave a note). – astex Dec 22 '13 at 06:45
9

Slight variation of Gerald's answer using keyword args

create pickleable object

image = {'data': im.tostring(), 'size':im.size, 'mode':im.mode}

or

image = dict(data=im.tostring(), size=im.size, mode=im.mode)

unpickle back to image

im = Image.fromstring(**image)
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
  • Does this mean that I don't need to store images in my application? I can just use the string that they serialize to and just hardcode it inside the application when I want to use the image? – Ogen Nov 15 '15 at 00:57
  • You technically *could* do that, but it's far better to keep it as an actual file... in either case it can be versioned along with your code, but having images kept as images means you can readily view them and know what media you have stored. If you're storing images as code, you're artificially inflating the size of your source files, making them more onerous to view and search, and making your media much harder to manage should you want to view and/or change that image. – kungphu Apr 25 '16 at 13:41