67

I am trying to manipulate a base64 encoded image in such a way as to rotate it at 90 angle. After this manipulation, I want to convert it back to base64 string. But unfortunately unable to achieve this yet.

Here is what I have done so far:

image_string = StringIO(base64.b64decode(base64_string_here))
image = Image.open(image_string)
angle = 90
rotated_image = image.rotate( angle, expand=1 )

Kindy help me how to convert this rotated_image to base64 string.

here's the dir() of rotated_image:

['_Image__transformer', '__doc__', '__getattr__', '__init__', '__module__', '__repr__', '_copy', '_dump', '_expand', '_makeself', '_new', 'category', 'convert', 'copy', 'crop', 'draft', 'filter', 'format', 'format_description', 'fromstring', 'getbands', 'getbbox', 'getcolors', 'getdata', 'getextrema', 'getim', 'getpalette', 'getpixel', 'getprojection', 'histogram', 'im', 'info', 'load', 'mode', 'offset', 'palette', 'paste', 'point', 'putalpha', 'putdata', 'putpalette', 'putpixel', 'quantize', 'readonly', 'resize', 'rotate', 'save', 'seek', 'show', 'size', 'split', 'tell', 'thumbnail', 'tobitmap', 'tostring', 'transform', 'transpose', 'verify']

M.javid
  • 6,387
  • 3
  • 41
  • 56
Hammad Qureshi
  • 1,006
  • 1
  • 11
  • 20

1 Answers1

170

Python 3

import base64
from io import BytesIO

buffered = BytesIO()
image.save(buffered, format="JPEG")
img_str = base64.b64encode(buffered.getvalue())

Python 2

import base64
import cStringIO

buffer = cStringIO.StringIO()
image.save(buffer, format="JPEG")
img_str = base64.b64encode(buffer.getvalue())
F Lekschas
  • 12,481
  • 10
  • 60
  • 72
Eugene V
  • 2,830
  • 1
  • 14
  • 8
  • 23
    I'd like to say that in python3.4 you should write `from io import BytesIO` and `buffer = BytesIO()`. Also keep in mind that `buffer` is already an existing builtin name (use `buffered` maybe). [The fine docs](https://docs.python.org/3/library/io.html#binary-i-o). – Paolo Mar 22 '16 at 21:39
  • 1
    `IOError: cannot write mode RGBA as JPEG` – User Jan 09 '19 at 01:57
  • 1
    @User this means image has alpha channel (known as transparency level in your image). In case you are safe to get rid of it, you can convert image to RGB before saving it to and converting to base64 string with next line: `image = image.convert("RGB")` – Eugene V Jan 10 '19 at 11:23
  • 10
    If someone what to write to an image, this is neccessary `img_base64 = bytes("data:image/jpeg;base64,", encoding='utf-8') + img_str` – Johnny May 20 '19 at 12:16
  • @User See https://github.com/python-pillow/Pillow/issues/2609#issuecomment-313922483 for a workaround – jtlz2 May 22 '19 at 10:40
  • @VictorJohn Really...? – jtlz2 May 22 '19 at 10:41
  • 4
    Sorry but does not work: I get a string like "b'iVBORw0KGgoAAAA....", aka the byte string...what I want is the canonical base64 string the one ending with "==" ... – Phate Jun 05 '19 at 08:53
  • @Phate, what did you do on this ? – Lutaaya Huzaifah Idris Jan 27 '21 at 00:28
  • 1
    @LutaayaHuzaifahIdris `from django.utils.encoding import force_str` then `force_str(img_str)` – R. Steigmeier Feb 18 '21 at 10:08
  • 2
    @Phate Use `.decode("")`. For example: `img_base64_str = img_base64.decode("utf-8")` – Chris Hayes Sep 05 '22 at 09:56
  • is there a way to compress the image string and reduce its size? – itsDanial Apr 18 '23 at 16:03