2010-09-15 25 views
96

Quiero codificar una imagen en una cadena utilizando el módulo base64. Me encontré con un problema sin embargo. ¿Cómo especifico la imagen que quiero codificar? Intenté usar el directorio en la imagen, pero eso simplemente lleva al directorio que está siendo codificado. Quiero que el archivo de imagen real sea codificado.Codificación de un archivo de imagen con base64

EDITAR

I cansada este fragmento:

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)) 

pero me sale el siguiente error:

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é estoy haciendo mal?

Respuesta

171

No estoy seguro de entender su pregunta. Asumo que está haciendo algo en la línea de:

import base64 

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

Tienes que abrir el archivo en primer lugar, por supuesto, y leer su contenido - no se puede simplemente pasar el camino a la función de codificación.

Editar: Bien, aquí hay una actualización después de haber editado su pregunta original.

En primer lugar, recuerde utilizar cadenas sin formato (prefijar la cadena con 'r') cuando utilice delimitadores de ruta en Windows, para evitar golpear accidentalmente un carácter de escape. En segundo lugar, Image.open de PIL acepta un nombre de archivo o un archivo (por ejemplo, el objeto debe proporcionar métodos de lectura, búsqueda y explicación).

Dicho esto, se puede utilizar cStringIO para crear un objeto, de un búfer de memoria:

import cStringIO 
import PIL.Image 

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

img = PIL.Image.open(file_like) 
img.show() 
+0

Necesita un poco más de ayuda, ver la edición. – rectangletangle

+0

Gracias, un problema más cuando imprimo la imagen decodificada obtengo la cadena 'ÿØÿà'. Sin embargo, cuando ejecuto esto solo como un sustituto de datos obtengo un error. La cadena codificada es mucho más larga para la comparación. Así que creo que es probable que almacene los datos de imagen. La cadena decodificada simplemente hace referencia a la cadena codificada o algo así? Parece demasiado corto para el almacenamiento de datos. – rectangletangle

+0

La salida impresa no es necesariamente igual al contenido real, depende de cómo y dónde la imprima. –

8

Como dije en la pregunta anterior, no hay necesidad de base64 codifican la cadena, que sólo produce hacer que el programa sea más lento. Sólo tiene que utilizar la 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)) 
... 

Ahora la imagen se almacena como una variable llamada image_data en un archivo llamado image.py Iniciar un intérprete fresca e importar el image_data

>>> from image import image_data 
>>> 
+0

Realmente no veo cómo repr() puede ser de alguna utilidad aquí. –

+4

@Ivo, Anteater quiere poder almacenar imágenes en archivos de Python. Estoy señalando que el uso de base64 es contraproducente porque los datos deben decodificarse cada vez que se carga el módulo. El uso de repr en su lugar significa que la cadena literal se almacena lista para su uso inmediato en el archivo .pyc sin proceso de furthur –

46

Con Python 2.x, puede trivialmente codificar utilizando .encode:

with open("path/to/file.png", "rb") as f: 
    data = f.read() 
    print data.encode("base64") 
+0

Un fragmento de decodificación también puede ser útil. –

5

Préstamos de lo Ivo van der Wijk y gnibbler HAV e desarrollado anteriormente, esta es una solución dinámica

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 __name__ == '__main__': 
    imagetopy('spot.png', 'wishes.py') 
    pytoimage('wishes') 

continuación, puede decidir para compilar el archivo de imagen de salida con Cython para que se enfríe. Con este método, puede agrupar todos sus gráficos en un solo módulo.

Cuestiones relacionadas