web-dev-qa-db-fra.com

Encodage d'un fichier image avec base64

Je veux encoder une image dans une chaîne en utilisant le module base64. J'ai cependant rencontré un problème. Comment spécifier l'image que je souhaite encoder? J'ai essayé d'utiliser le répertoire pour l'image, mais cela conduit simplement à l'encodage du répertoire. Je veux que le fichier image soit encodé.

EDIT

J'ai essayé cet extrait:

with open("C:\Python26\seriph1.BMP", "rb") as f:
    data12 = f.read()
    UU = data12.encode("base64")
    UUU = base64.b64decode(UU)

    print UUU

    self.image = ImageTk.PhotoImage(Image.open(UUU))

mais j'obtiens l'erreur suivante:

Traceback (most recent call last):
  File "<string>", line 245, in run_nodebug
  File "C:\Python26\GUI1.2.9.py", line 473, in <module>
    app = simpleapp_tk(None)
  File "C:\Python26\GUI1.2.9.py", line 14, in __init__
    self.initialize()
  File "C:\Python26\GUI1.2.9.py", line 431, in initialize
    self.image = ImageTk.PhotoImage(Image.open(UUU))
  File "C:\Python26\lib\site-packages\PIL\Image.py", line 1952, in open
    fp = __builtin__.open(fp, "rb")
TypeError: file() argument 1 must be encoded string without NULL bytes, not str

Qu'est-ce que je fais mal?

138
rectangletangle

Je ne suis pas sûr de comprendre votre question. Je suppose que vous faites quelque chose dans le sens de:

import base64

with open("yourfile.ext", "rb") as image_file:
    encoded_string = base64.b64encode(image_file.read())

Bien sûr, vous devez d'abord ouvrir le fichier et lire son contenu - vous ne pouvez pas simplement indiquer le chemin d'accès à la fonction encoder.

Edit: Ok, voici une mise à jour après que vous ayez modifié votre question initiale.

Tout d'abord, pensez à utiliser des chaînes brutes (préfixez la chaîne par "r") lorsque vous utilisez des délimiteurs de chemin d'accès sous Windows, afin d'éviter de heurter accidentellement un caractère d'échappement. Deuxièmement, Image.open de PIL accepte un nom de fichier ou un fichier (c'est-à-dire que l'objet doit fournir des méthodes de lecture, de recherche et d'information).

Ceci étant dit, vous pouvez utiliser cStringIO pour créer un tel objet à partir d'un tampon de mémoire:

import cStringIO
import PIL.Image

# assume data contains your decoded image
file_like = cStringIO.StringIO(data)

img = PIL.Image.open(file_like)
img.show()
255
Jim Brissom

Avec python 2.x, vous pouvez encoder de manière triviale en utilisant .encode:

with open("path/to/file.png", "rb") as f:
    data = f.read()
    print data.encode("base64")
53
Ivo van der Wijk

Comme je l'ai dit dans votre question précédente, il n'est pas nécessaire de coder la chaîne en base64, cela ralentira le programme. Il suffit d'utiliser le repr

>>> with open("images/image.gif", "rb") as fin:
...  image_data=fin.read()
...
>>> with open("image.py","wb") as fout:
...  fout.write("image_data="+repr(image_data))
...

Maintenant, l'image est stockée en tant que variable appelée image_data dans un fichier nommé image.py Lance un nouvel interpréteur et importe les données image_data.

>>> from image import image_data
>>>
10
John La Rooy

Emprunter de quoi Ivo van der Wijk et gnibbler se sont développés plus tôt, c'est une solution dynamique

import cStringIO
import PIL.Image

image_data = None

def imagetopy(image, output_file):
    with open(image, 'rb') as fin:
        image_data = fin.read()

    with open(output_file, 'w') as fout:
        fout.write('image_data = '+ repr(image_data))

def pytoimage(pyfile):
    pymodule = __import__(pyfile)
    img = PIL.Image.open(cStringIO.StringIO(pymodule.image_data))
    img.show()

if __== '__main__':
    imagetopy('spot.png', 'wishes.py')
    pytoimage('wishes')

Vous pouvez ensuite décider de compiler le fichier image de sortie avec Cython pour le rendre cool. Avec cette méthode, vous pouvez regrouper tous vos graphiques dans un seul module.

7
iChux

La première réponse imprimera une chaîne avec le préfixe b '. Cela signifie que votre chaîne ressemblera à ceci: b'your_string 'Pour résoudre ce problème, ajoutez la ligne de code suivante.

encoded_string= base64.b64encode(img_file.read())
print(encoded_string.decode('utf-8'))
4
CodeSpeedy