2010-09-15 89 views
96

Tôi muốn mã hóa hình ảnh thành chuỗi bằng mô-đun base64. Tôi đã gặp phải một vấn đề. Làm cách nào để chỉ định hình ảnh tôi muốn được mã hóa? Tôi đã thử sử dụng thư mục cho hình ảnh, nhưng điều đó chỉ đơn giản là dẫn đến thư mục đang được mã hóa. Tôi muốn tập tin hình ảnh thực tế được mã hóa.Mã hóa tệp hình ảnh với base64

EDIT

Tôi mệt mỏi đoạn này:

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

nhưng tôi nhận được lỗi sau:

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 

Tôi đang làm gì sai?

Trả lời

171

Tôi không chắc mình hiểu câu hỏi của bạn. Tôi cho rằng bạn đang làm điều gì đó dọc theo các dòng:

import base64 

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

Trước tiên, bạn phải mở tệp và đọc nội dung của tệp - bạn không thể chuyển đường dẫn đến hàm mã hóa.

Chỉnh sửa: Ok, đây là bản cập nhật sau khi bạn đã chỉnh sửa câu hỏi gốc của mình.

Trước hết, hãy nhớ sử dụng chuỗi thô (tiền tố chuỗi có 'r') khi sử dụng dấu phân tách đường dẫn trên Windows, để ngăn vô tình nhấn ký tự thoát. Thứ hai, Image.open của PIL chấp nhận một tên tập tin, hoặc một tập tin tương tự (tức là, đối tượng phải cung cấp các phương thức đọc, tìm và cho biết).

đó đang được nói, bạn có thể sử dụng cStringIO để tạo ra như một đối tượng từ một bộ nhớ đệm:

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

Cần trợ giúp thêm một chút, hãy xem chỉnh sửa. – rectangletangle

+0

Cảm ơn, một vấn đề nữa khi tôi in hình ảnh đã giải mã, tôi nhận được chuỗi 'ÿØÿà'. Tuy nhiên, khi tôi chạy điều này một mình như là một thay thế cho dữ liệu tôi nhận được một lỗi. Chuỗi được mã hóa dài hơn nhiều để so sánh. Vì vậy, tôi nghĩ rằng có khả năng lưu trữ dữ liệu hình ảnh. chuỗi giải mã có đơn giản tham chiếu chuỗi được mã hóa hay gì đó không? Dường như quá ngắn để lưu trữ dữ liệu. – rectangletangle

+0

Đầu ra được in không nhất thiết phải bằng với nội dung thực tế - nó phụ thuộc vào cách thức và nơi bạn in. –

8

Như tôi đã nói trong câu hỏi trước đó của bạn, không có cần phải base64 mã hóa chuỗi, nó sẽ chỉ làm cho chương trình chậm hơn. Chỉ cần sử dụng 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)) 
... 

Bây giờ hình ảnh được lưu trữ như là một biến gọi là image_data trong một tập tin gọi là image.py Bắt đầu một thông dịch viên tươi và nhập khẩu các image_data

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

Tôi không thực sự thấy cách repr() có thể được sử dụng bất kỳ ở đây. –

+4

@Ivo, Anteater muốn có thể lưu trữ hình ảnh trong các tệp python. Tôi chỉ ra rằng việc sử dụng base64 là phản tác dụng vì dữ liệu cần được giải mã mỗi khi mô-đun được tải. Thay vào đó, sử dụng repr có nghĩa là chuỗi ký tự được lưu trữ sẵn sàng để sử dụng ngay lập tức trong tệp .pyc không có xử lý furthur –

46

Với python 2.x, bạn có thể trivially mã hóa sử dụng .encode:

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

Đoạn mã giải mã cũng có thể hữu ích. –

5

vay từ những gì Ivo van der Wijkgnibbler hav e phát triển trước đó, đây là một giải pháp năng động

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

Sau đó bạn có thể quyết định để biên dịch các tập tin hình ảnh đầu ra với Cython để làm cho nó mát mẻ. Với phương pháp này, bạn có thể gộp tất cả đồ họa của mình thành một mô-đun.

Các vấn đề liên quan