Django에서 AWS s3 이미지 업로드 및 리사이징 하기

Kay·2020년 4월 4일
6

먼저 이미지 업로드에 필요한 boto3와 이미지 리사이징에 필요한 Pillow를 인스톨 한다.
pip install boto3
pip install Pillow

view를 작성하기에 앞서 import 해준다.

import boto3            # s3에 이미지를 업로드 할 때 필요
import uuid             # 파일이름에 난수를 부여하기 위해 uuid를 사용 
from PIL import Image   # 이미지 리사이징에 필요한 Pillow
from io  import BytesIO # Pillow로 리사이징한 이미지를 다시 Bytes화

이미지 업로드, 이미지 리사이징과 관련하여, 검색해보면 수많은 질문과 답변이 존재한다.
하나하나 적용해보고 오류를 만나고 수정하다 보니 하루가 금방 지나갔고, 그래도 원래 의도했던 대로 동작하는 코드가 남아 기록으로 남겨본다.

class ProfileUploadView(View):
    s3_client = boto3.client(
        's3',
        aws_access_key_id     = S3['Access_Key_ID'],
        aws_secret_access_key = S3['Secret_Access_Key']
    )
    def post(self, request):
        try:
            image  = request.FILES['filename']
      [1]   im     = Image.open(image)
      [2]   im     = im.resize((400, 400))
      [3]   buffer = BytesIO()
      [4]   im.save(buffer, "JPEG")
      [5]   buffer.seek(0)
            
            url_generator = str(uuid.uuid4())
            self.s3_client.upload_fileobj(
      [6]       buffer,
                "bucket_name",
                url_generator,
      [7]       ExtraArgs = {
                    "ContentType": 'image/jpeg'
                }
            )
            image_url = f'{S3["Address"]}{url_generator}'
            
            return JsonResponse({'image_url' : image_url}, status = 200)
        
        except KeyError:
            return JsonResponse({"message" : "INVALID_KEYS"}, status = 400)

이미지 리사이징이 필요 없는 경우에는 [1]~[5]를 생략한 뒤 [6]의 "buffer"를 "image"로 바꾸어 업로드하면 된다.

[1] 이미지를 열어 (Pillow가 하는 일)
[2] 리사이징 해준 뒤 (Pillow가 하는 일)
[3]~[4] BytesIO를 통해 bytes화 하여 저장하고
[5] bytes화 한 객체가 잘 저장되도록 해준다.

[5]와 관련하여 참고:
https://velog.io/@valentin123/TIL-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EB%A6%AC%EC%82%AC%EC%9D%B4%EC%A7%95-S3-%EC%97%85%EB%A1%9C%EB%93%9C

https://stackoverflow.com/questions/26879981/writing-then-reading-in-memory-bytes-bytesio-gives-a-blank-result

처음에는 [7]의 ExtraArgs 부분을 생략했었는데 파일 업로드는 정상적으로 작동 하지만, url을 클릭했을 때 브라우저에서 이미지가 보이는 것이 아니라 강제로(?) 다운로드가 되어 또 열심히 구글링을 해보았다.

무려 7년 전에 작성된 질문/답변이었지만 아직도 도움받을 수 있다는게 너무 신기했다.
참고 :
https://stackoverflow.com/questions/14150854/aws-s3-display-file-inline-instead-of-force-download

이 블로깅이 미래의 나와 미래의 누군가에게 도움이 되면 좋겠다.😌

profile
new blog✨ https://kay-log.tistory.com/

3개의 댓글

comment-user-thumbnail
2020년 11월 19일

완전 도움됐어요! 감사합니다 😌

1개의 답글
comment-user-thumbnail
2022년 5월 16일

많은 도움이 되었습니다:) 정말 감사합니다

답글 달기