base64로 이미지 파일 인코딩


161

base64 모듈을 사용하여 이미지를 문자열로 인코딩하고 싶습니다. 그래도 문제가 발생했습니다. 인코딩 할 이미지를 어떻게 지정합니까? 디렉토리를 이미지에 사용하려고 시도했지만 디렉토리가 인코딩되도록합니다. 실제 이미지 파일을 인코딩하고 싶습니다.

편집하다

이 스 니펫을 시도했습니다.

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

내가 뭘 잘못하고 있죠?

답변:


299

귀하의 질문을 이해하지 못했습니다. 나는 당신이 다음 라인을 따라 무언가를하고 있다고 가정합니다 :

import base64

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

물론 파일을 먼저 열고 내용을 읽어야합니다. 단순히 인코딩 함수의 경로를 전달할 수 없습니다.

편집 : 좋아, 여기는 원래 질문을 편집 한 후의 업데이트입니다.

우선, Windows에서 경로 구분 기호를 사용할 때 실수로 이스케이프 문자를 누르지 않도록 원시 문자열 ( 'r'로 문자열 접두어)을 사용해야합니다. 둘째, PIL의 Image.open은 파일 이름 또는 파일과 같은 형식을 허용합니다 (즉, 개체는 읽기, 찾기 및 말하기 방법을 제공해야합니다).

즉, 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()

1
고맙게도, 디코딩 된 이미지를 인쇄 할 때 한 가지 더 문제는 문자열 'ÿØÿà'입니다. 그러나 데이터를 대신하여 이것을 단독으로 실행하면 오류가 발생합니다. 인코딩 된 문자열은 비교하기에 훨씬 더 깁니다. 이미지 데이터가 저장되어 있다고 생각합니다. 디코딩 된 문자열은 단순히 인코딩 된 문자열이나 무언가를 참조합니까? 데이터 저장에 비해 너무 짧은 것 같습니다.
rectangletangle

인쇄 된 출력물이 실제 내용과 반드시 ​​같을 필요는 없습니다. 인쇄 방법과 위치에 따라 다릅니다.
Jim Brissom

8
필자의 경우 base64.b64encode(fh.read()).decode()html 파일에서 사용할 문자열을 얻으려면 디코딩해야 합니다.
qed

1
base64.b64encode (fh.read ()). decode () 은 미묘하지만 @qed도 필요했습니다. 감사합니다. 차이점은 바이트와 다른 문자열을 반환하는 것입니다 ... 내 SOAP 서버는 디코딩하지 않고 그것을 삼킬 수 없습니다!
zzart

57

python 2.x에서는 .encode를 사용하여 간단하게 인코딩 할 수 있습니다.

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

12

첫 번째 답변은 접두사가 b '인 문자열을 인쇄합니다. 즉, 문자열이 b'your_string '과 같습니다.이 문제를 해결하려면 다음 코드 줄을 추가하십시오.

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

2
좋은 답변처럼 보이지만 웹 사이트 홍보 목적으로 게시하는 것을 삼가십시오. 그러나 프로필에 링크를 추가 할 수 있습니다.
halfer

1
(실수로, 답변 순서는 여기에 의존 할 수 없으므로 "첫 번째 답변"과 같은 댓글은 피할 가치가 있습니다. 처음 나타나는 답변은 시간이 지남에 따라 변경 될 수 있습니다. :-))
1/2 1/2

이 답변의 원래 버전에서는 자신의 사이트 또는 연결된 사이트에 연결된 것처럼 보입니다. 당신은 이러한 사이트에 링크를 할 경우, 당신은 이 사이트의 것을 공개해야합니다 . 제휴를 공개하지 않으면 스팸으로 간주됩니다. 참조 : "좋은"자기 홍보를 의미한다 무엇? 그리고 자기 진흥에 대한 도움말 센터 . 공개는 명시 적이어야하지만 공식적 일 필요는 없습니다. 자신의 개인 컨텐츠 인 경우 "내 사이트에서 ...", "내 블로그에서 ..."등과 같이 될 수 있습니다.
Makyen

@Makyen 제안에 감사드립니다. 내 사이트라는 것을 공개하겠습니다. 내 사이트임을 밝히기 위해 지금 답변을 편집하는 것이 합법적입니까? 아니면 편집해서는 안됩니다.
CodeSpeedy

9

이전 질문에서 말했듯이 문자열을 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 . 새로운 인터프리터 시작 및 image_data 가져 오기

>>> from image import image_data
>>>

repr ()이 어떻게 사용될 수 있는지 실제로 알지 못합니다.
Ivo van der Wijk

6
@Ivo, Anteater는 이미지를 파이썬 파일로 저장할 수 있기를 원합니다. 나는 모듈이로드 될 때마다 데이터를 디코딩해야하기 때문에 base64를 사용하는 것이 비생산적이라고 지적합니다. 대신 repr을 사용하면 리터럴 문자열이 furthur 처리없이 .pyc 파일에 즉시 사용할 수 있도록 저장됩니다.
John La Rooy

7

어떤에서 대출 이보의 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 으로 출력 이미지 파일을 컴파일하여 멋지게 만들 수 있습니다. 이 방법을 사용하면 모든 그래픽을 하나의 모듈로 묶을 수 있습니다.


7
import base64
from PIL import Image
from io import BytesIO

with open("image.jpg", "rb") as image_file:
    data = base64.b64encode(image_file.read())

im = Image.open(BytesIO(base64.b64decode(data)))
im.save('image1.png', 'PNG')

1
이 답변은 정말로 최상위에 있어야합니다 ... 최고의 답변-감사합니다!
루터
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.