PIL을 사용하여 PNG 이미지를 문자열에 쓰는 방법은 무엇입니까?


100

PIL을 사용하여 이미지를 생성했습니다 . 메모리의 문자열에 어떻게 저장할 수 있습니까? 이 Image.save()메서드에는 파일이 필요합니다.

이러한 이미지를 사전에 여러 개 저장하고 싶습니다.

답변:


194

BytesIO클래스를 사용하여 파일처럼 동작하는 문자열 주위에 래퍼를 가져올 수 있습니다 . BytesIO객체는 파일과 동일한 인터페이스를 제공하지만, 단지 메모리에 내용을 저장합니다

import io

with io.BytesIO() as output:
    image.save(output, format="GIF")
    contents = output.getvalue()

format매개 변수를 사용하여 출력 형식을 명시 적으로 지정해야합니다 . 그렇지 않으면 자동으로 감지하려고 할 때 PIL에서 오류가 발생합니다.

파일에서 이미지를로드 한 경우 format원본 파일 형식을 포함 하는 매개 변수가 있으므로이 경우 format=image.format.

io모듈을 도입하기 전에 이전 Python 2 버전 에서는 StringIO모듈을 대신 사용했을 것입니다.


1
예! 이것이 바로 제가 찾던 것입니다. 나는 파이썬, 문자열, 리더, 라이터, 버퍼의 모든 조합을 검색했지만 아무것도 생각하지 못했습니다. 감사!
rik.the.vik

2
나를 위해 작동하지 않습니다 : (I got this KeyError in Imaging / PIL / Image.pyc line 1423-> raise KeyError (ext) # unknown extension
Radian

6
@Radian, save () 메서드에 대한 PIL 문서는 다음과 같이 말합니다. You can use a file object instead of a filename. In this case, you must always specify the format.따라서 첫 번째 인수가 파일 객체 인 경우 형식 (예 :) 인 두 번째 인수를 전달해야합니다 'PNG'.
Su Zhang

1
현재 Python 버전에서 StringIO는 io 패키지에 from io import StringIO
있으므로

4
당신이 사용하는 더 나은 수image.save(output, format=image.format)
reetesh11


24

sth의 솔루션이 나를 위해 작동하지
않았기 때문에 ...

Imaging / PIL / Image.pyc line 1423-> raise KeyError (ext) # 알 수없는 확장

StringIO 케이스에 존재하지 않는 파일 이름의 확장자에서 형식을 감지하려고했습니다.

매개 변수에서 직접 형식을 설정하여 형식 감지를 우회 할 수 있습니다.

import StringIO
output = StringIO.StringIO()
format = 'PNG' # or 'JPEG' or whatever you want
image.save(output, format)
contents = output.getvalue()
output.close()

14

save()파일과 같은 객체와 경로를 취할 수 있으므로 다음과 같은 메모리 내 버퍼를 사용할 수 있습니다 StringIO.

buf = StringIO.StringIO()
im.save(buf, format='JPEG')
jpeg = buf.getvalue()

감사합니다. StringIO-그게 내가 필요한 것입니다.
maxp

save () 인터페이스는 PNG, JPEG 또는 실제 파일 형식을 가져올 때 tostring () 인터페이스보다 훨씬 깨끗합니다.
Kekoa

13

최신 버전 (2017 년 중반 Python 3.5 및 Pillow 4.0 기준) :

StringIO는 더 이상 예전처럼 작동하지 않는 것 같습니다. BytesIO 클래스는이를 처리하는 적절한 방법입니다. Pillow의 저장 기능은 문자열을 첫 번째 인수로 예상하며 놀랍게도 StringIO를 인식하지 않습니다. 다음은 이전 StringIO 솔루션과 유사하지만 그 자리에 BytesIO가 있습니다.

from io import BytesIO
from PIL import Image

image = Image.open("a_file.png")
faux_file = BytesIO()
image.save(faux_file, 'png')

2
image_data = faux_file.getvalue ()의 목적은 무엇입니까?
라이언

@Ryan 좋은 캐치, 전혀 목적이 없습니다. 테스트에서 남겨져 마침내 제거되었습니다.
mightypile

9

"사전에 이러한 이미지를 많이 저장하고 싶습니다"라고 말하면 이것이 메모리 내 구조인지 아닌지 명확하지 않습니다.

메모리에서 이미지를 온유하게 만들기 위해이 작업을 수행 할 필요가 없습니다. image사전에 개체를 보관하십시오 .

딕셔너리를 파일에 쓰려면 im.tostring()메소드와 Image.fromstring()함수 를보고 싶을 것입니다.

http://effbot.org/imagingbook/image.htm

im.tostring () => 문자열

표준 "원시"인코더를 사용하여 픽셀 데이터가 포함 된 문자열을 반환합니다.

Image.fromstring (모드, 크기, 데이터) => 이미지

표준 "원시"디코더를 사용하여 문자열의 픽셀 데이터에서 이미지 메모리를 만듭니다.

"형식"(.jpeg, .png 등)은 파일을 교환 할 때 디스크에서만 중요합니다. 파일을 교환하지 않는 경우 형식은 중요하지 않습니다.


2
그는 PNG 형식을 원시 픽셀 데이터로 줄이는 것이 아니라 유지하려는 것 같습니다.
Ben Blank
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.