2010-09-15 5 views
96

Я хочу кодировать изображение в строку, используя модуль base64. Однако я столкнулся с проблемой. Как указать изображение, которое я хочу закодировать? Я попытался использовать каталог для изображения, но это просто приводит к кодировке каталога. Я хочу, чтобы фактический файл изображения был закодирован.Кодирование файла изображения с base64

EDIT

Я устал этот фрагмент:

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

, но я получаю следующее сообщение об ошибке:

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 

Что я делаю неправильно?

ответ

171

Я не уверен, что понимаю ваш вопрос. Я предполагаю, что вы делаете что-то вдоль линий:

import base64 

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

Вы должны открыть файл первый, конечно, и прочитать его содержимое - вы не можете просто пройти путь к функции кодирования.

Редактировать: Итак, это обновление после того, как вы отредактировали исходный вопрос.

Прежде всего, не забудьте использовать необработанные строки (префикс строки с «r») при использовании ограничителей маршрутов в Windows, чтобы предотвратить случайное попадание escape-символа. Во-вторых, Image.open PIL либо принимает имя файла, либо файл-подобный (то есть объект должен предоставлять методы чтения, поиска и рассылки).

При этом, вы можете использовать cStringIO создать такой объект из буфера памяти:

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

Нужна дополнительная помощь, см. Редактирование. – rectangletangle

+0

Спасибо, еще одна проблема, когда я печатаю декодированное изображение, я получаю строку 'ÿØÿà'. Однако, когда я запускаю это как замену данных, я получаю сообщение об ошибке. Закодированная строка намного длиннее для сравнения. Поэтому я думаю, что, вероятно, хранят данные изображения. декодированная строка просто ссылается на закодированную строку или что-то еще? Это кажется слишком коротким для хранения данных. – rectangletangle

+0

Печатный результат не обязательно равен фактическому содержимому - это зависит от того, как и где вы его печатаете. –

8

Как я говорил в предыдущем вопросе, нет необходимости base64 кодирования строки, то это будет только сделать программу медленнее. Просто используйте 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)) 
... 

Теперь изображение хранится в переменной с именем image_data в файле image.py Start свежий переводчик и импортировать image_data

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

Я действительно не вижу, как функция repr() может быть использована здесь. –

+4

@Ivo, Anteater хочет иметь возможность хранить изображения в файлах python. Я указываю, что использование base64 контрпродуктивно, потому что данные необходимо декодировать каждый раз, когда модуль загружается. Использование выражения вместо этого означает, что литеральная строка хранится в готовности для немедленного использования в файле .pyc без обработки furthur. –

46

С Python 2.x, вы можете тривиальный закодировать с помощью .encode:

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

Возможно, также будет полезен фрагмент декодирования. –

5

заимствования из того, что Ivo van der Wijk и gnibbler ВГА е разработаны ранее, это динамическое решение

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

Вы можете решить скомпилировать файл изображения на выходе с Cython сделать это круто. С помощью этого метода вы можете объединить все свои графики в один модуль.

Смежные вопросы