body = s3_client.get_object(Bucket=settings.AWS_STORAGE_BUCKET_NAME ,Key=ret['image'])["Body"]
raw_data = body.read() # binary
ret['image'] = base64.b64encode(raw_data).decode('utf-8') # string
다음과 같이 이미지의 Binary 코드를 JSON에 입력하기 위해 utf-8(unicode) 문자열로 디코드되는 과정을 추적해보고자 한다.
>>> with open('example.png', 'rb') as f:
>>> a = f.read()
다음과 같이 이미지 파일을 binary로 열면 다음과 같은 결과가 나온다.
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x02\x00\x00\x00\x01\x08\x06\x0...
모든 컴퓨터에서 동일하게 문자열을 해석하고 사용하기 위해 만들어진 표준.
ASCII는 기본적으로 7비트 데이터이다. 그 이유는 127개 만으로도 표준에서 정의한 문자 모두를 표현할 수 있기 때문이다.
즉 마지막 비트는 0이 된다.
하지만 우리가 변환할 이미지의 바이너리 코드는 8비트로 이루어져있다.
따라서 8비트로 이루어진 바이너리 코드를 ASCII 코드처럼 변경하는 "인코딩" 작업이 필요다.
(* 이 글 제목에 아래와 같은 아이콘이 보이는 사람도 있을 것이고 이상한 문자로 보일 수도 있다. 이는 현재 본인이 사용하는 시스템에 따라 저 아이콘이 보일지 안보일지 결정되기 때문이다.)
Base64는 ASCII 코드에서 127개의 문자만으로 인코딩하는 방식이다.
이로써 얻는 장점은 어떤 운영체제던 ASCII 코드에서 127개만큼은 동일하게 해석한다는 점이다.
Binary를 Base64로 인코딩한 결과는 아래와 같다.
>>> base64.b64encode(a)
b'iVBORw0KGgoAAAANSUhEUgAAAAIAAAABCAYAAAD0In+KAAABWmlDQ1BJQ0MgUHJvZmlsZQAAKJF1kD
결과 문자를 보면 알 수 있듯이 바이너리 코드임을 알 수 있다.
JSON에 넣기 위해 문자열로 표현해야한다.
UTF-8 방식을 통해 바이너리 코드를 유니코드로 변환하면(base64 바이너리 코드를 유니코드로 디코딩) 다음과 같다.
>>> encoded = base64.b64encode(a)
>>> encoded.decode('utf-8')
'iVBORw0KGgoAAAANSUhEUgAAAAIAAAABCAYAAAD0In+KAAABWmlDQ1BJQ0MgUHJvZmlsZQAAKJF1kD
앞에 b'
빼고 동일함을 볼 수 있다. 그 이유는 앞에서 설명한 바와 같이 ASKII코드의 127개 문자만으로 인코딩했기 때문이다.
참고: https://taehyeki.tistory.com/155 - 바이너리, 인코딩, 디코딩, ASCII, MIME, base64를 쉽게 이해하자! [taehyeki]