노래하듯 이야기하고, 춤추듯 정복하라.

장고 이미지 파일업로드 & 썸네일 생성하기 본문

프로그래밍/Django

장고 이미지 파일업로드 & 썸네일 생성하기

hyeoke 2017. 10. 10. 15:40

필자가 파이썬 웹 프로그래밍(실전편) _Django를 활용한 쉽고 빠른 웹 개발 을 읽으며 장고를 공부하 던 중, 또 다른 장고 학습자들에게 팁이 될까하여 포스팅 해 본다. 오늘 포스팅할 내용은 장고를 통해 "이미지 파일 업로드 & 썸네일 생성하기" 이다.


1. models.py 코딩하기

이미지 업로드 기능 만들기 위해서는 아래와 같이 models.py에서 이미지 데이터를 사용(보내기, 불러오기 등)하기 위한 Image 속성을 가진 객체를 만들어 줘야 한다.

from photo.fields import ThumbnailImageField

class Photo(models.Model):
    image = ThumbnailImageField(upload_to='photo/%Y/%m)

여기서 ThumbanilImageField는 여러분이 fields.py 파일을 생성하여 그 안에 직접 만들어 줘야 한다.


2. fields.py 코딩하기

class ThumbnailImageFieldFile(ImageFieldFile):
    def _get_thumb_path(self):
        return _add_thumb(self.path)
    thumb_path = property(_get_thumb_path)

    def _get_thumb_url(self):
        return _add_thumb(self.url)
    thumb_url = property(_get_thumb_url)

    def save(self, name, content, save=True):
        super(ThumbnailImageFieldFile, self).save(name, content, save)
        img = Image.open(self.path)
        size = (128, 128)
        img.thumbnail(size, Image.ANTIALIAS)

        background = Image.new('RGBA', size, (255, 255, 255, 0))
        background.paste(img, (int((size[0]-img.size[0])/2), int((size[1]-img.size[1])/2) ))
        background.save(self.thumb_path, 'JPEG') 

    def delete(self, save=True):
        if os.path.exists(self.thumb_path):
            os.remove(self.thumb_path)
        super(ThumbnailImageFieldFile, self).delete(save)

class ThumbnailImageField(ImageField):
    attr_class = ThumbnailImageFieldFile

    def __init__(self, thumb_width=128, thumb_height=128, *args, **kwargs):
        self.thumb_width = thumb_width
        self.thumb_height = thumb_height
        super(ThumbnailImageField, self).__init__(*args, **kwargs)

먼저 ThumbanilImageFieldFile 클래스를 코딩하고 ThumbnailImgaeField 클래스 안의 attr_class 변수를 통해 ThumbanilImageFieldFile 객체를 받아낸다. 이 코드에서 주의 할 곳은 16, 18 번째 줄이다. 


이미지 파일업로드 기능을 만들기 위해서는 사전에 Pillow라는 장고가 제공하는 패키지를 미리 설치 하였을 것이다. 그런데 여러분이 pillow 4.2이상 버전을 설치하였다면, admin 페이지에서 사진을 업로드하는 과정에서 에러가 발생할 것이다. 바로 아래 사진과 같은 "cannot write mode RGBA as JPEG" issue 이다.

이 문제는 장고 측에서 컴퓨터가 이미지의 특정영역을 가리키거나 제어하는 특수한 채널인 Alpha Channel에서 .JPEG 파일이 합리적이지 못하다고 판단하여, Pillow 4.2버전부터는 지원하지 않는 것으로 판단 된다. 좀 더 자세한 토론 내용은 https://github.com/python-pillow/Pillow/issues/2609 이 링크를 참고해 보기 바란다. 

3. "cannot write mode RGBA as JPEG" issue 해결하기!

첫 번째 방법

-> 16번째 줄 바로 밑에 아래와 같은 코드를 추가해 준다.

background = background.convert('RGB') # Resolve "cannot write mode RGBA as JPEG" issue 

두 번째 방법

-> 18번째 줄을 아래와 같이 바꿔준다. JPEG 대신 PNG 사용하기

        background.save(self.thumb_path, 'PNG') # PNG is really the only reasonable choice


'프로그래밍 > Django' 카테고리의 다른 글

파이썬 & 장고 스터디 내용 _10월11일  (4) 2017.10.11
Django debug toolbar 사용법  (1) 2017.09.30
파이썬 및 장고 설치하기  (1) 2017.09.28
Comments