How to convert Image PIL into Base64 without saving

15,568

Solution 1

I found the solution. Hope this helps !

img = Image.fromarray(data, 'RGB')                  #Crée une image à partir de la matrice
buffer = BytesIO()
img.save(buffer,format="JPEG")                  #Enregistre l'image dans le buffer
myimage = buffer.getvalue()                     
print "data:image/jpeg;base64,"+base64.b64encode(myimage)

Solution 2

@florian answer helped me a lot but base64.b64encode(img_byte) returned bytes so I needed to decode it to string before concatenation (using python 3.6):

def img_to_base64_str(self, img):
    buffered = BytesIO()
    img.save(buffered, format="PNG")
    buffered.seek(0)
    img_byte = buffered.getvalue()
    img_str = "data:image/png;base64," + base64.b64encode(img_byte).decode()

Solution 3

You can use base64 library like this:

import base64

base64.b64encode(img.tobytes())

See tobytes() method of Image object.

Solution 4

Or you can use something like this:

import glob
import random
import base64

from PIL import Image
from io import BytesIO
import io


def get_thumbnail(path):
    path = "\\\\?\\"+path # This "\\\\?\\" is used to prevent problems with long Windows paths
    i = Image.open(path)    
    return i

def image_base64(im):
    if isinstance(im, str):
        im = get_thumbnail(im)
    with BytesIO() as buffer:
        im.save(buffer, 'jpeg')
        return base64.b64encode(buffer.getvalue()).decode()

def image_formatter(im):
    return f'<img src="data:image/jpeg;base64,{image_base64(im)}">'

Just pass path of image in get_thumbnail function and image_formatter to display it in HTML.

Share:
15,568

Related videos on Youtube

florian
Author by

florian

Updated on May 25, 2022

Comments

  • florian
    florian almost 2 years

    I generate an image with Python, and I need to convert this Pil Image into a Base64, without saving this one into any folder...

    I have some data, and I get RGB img with the line below:

    img = Image.fromarray(data,'RGB')
    

    What is the simple way to convert this PIL into base64 ?(I can't open a file image because I must not save the img) ?

    Thank you for your help

    With Node JS, I can get the correct base64 with these lines :

    pythonShell= require("python-shell");
    
    app.post('/index/gen/',urlencodedParser, function (req,res){ 
      pythonShell.run('minigen.py', function (err, results) {
      if (err) throw err; 
      var img = base64img.base64Sync('./images/miniature.jpg');
      res.send(img); }); 
    }) 
    

    But I have to save the file if I use NodeJS...

    this is the code to generate the matrix from the image, you don't need to know what is in data ;)

    image = Image.open("./carte/"+fichier)              
    image = image.resize((400,400),Image.ANTIALIAS)     
    w,h = image.size                                    
    tab = numpy.array(image)                            
    data = numpy.zeros((h, w, 3), dtype=numpy.uint8)
    
    • James Kent
      James Kent over 6 years
      are you sure you want to convert the PIL? i would have thought it would make more sense to convert you data array?
    • florian
      florian over 6 years
      I must convert the data into an RGB image.And then convert this image object to base64
    • bv.
      bv. about 5 years
  • florian
    florian over 6 years
    After the conversion into RGB image ? I don't have correct values by doing this
  • Tomáš Linhart
    Tomáš Linhart over 6 years
    @florian What do you mean by correct values? Base64 just encodes binary data into ASCII characters, which is what you asked for.
  • florian
    florian over 6 years
    Our API also works with nodejs and as we try to do the same thing with it, we can display the image in our navigator... Which is impossible with the base64 that we obtain with your method
  • Tomáš Linhart
    Tomáš Linhart over 6 years
    Where do data in img = Image.fromarray(data,'RGB') come from and what do they represent? There's a warning regarding compressed formats like JPEG in the documentation to Image.tobytes() method that I referenced in the answer.
  • florian
    florian over 6 years
    it's the matrix from the image
  • Tomáš Linhart
    Tomáš Linhart over 6 years
    Can you share the part of code that populates that data object?
  • Tomáš Linhart
    Tomáš Linhart over 6 years
    If data = numpy.zeros((h, w, 3), dtype=numpy.uint8) isn't it just all zero? Probably something you didn't want.
  • florian
    florian over 6 years
    No, don't worry, the script make many colors for an altimetric map ;)