SSAMKO의 개발 이야기

pillow - 이미지 리사이즈 하기 | Django 본문

Django

pillow - 이미지 리사이즈 하기 | Django

SSAMKO 2020. 5. 8. 09:51
반응형

인스타그램 클론 코딩 중 이미지를 받아서 저장할 때, 

모바일 특화 컨텐츠니까 굳이 큰 사이즈 이미지로 저장할 필요가 없겠다 싶어서

너비를 700픽셀로 리사이즈 할 필요가 있었다.

 

# views.py
def write(request):
    template_name = 'post.html'
    context = {}
    
    if request.method == 'POST':
        writer = request.POST.get('writer')
        text = request.POST.get('context')
        
        # 이미지는 option
        try:
            image = request.FILES['visitor_image']
            # image resize required
            image = rescale(image, 700)
        except:
            image = False
        
        new_post = Visitor(writer=writer,
                           text=text)
        if image:
            new_post.image = image
        new_post.save()
        
        return redirect('/namustagram')

    return render(request, template_name, context)
간단한 포맷이라 굳이 form을 사용한 class view를 쓰지 않고, 함수형 view를 사용했다.

포스팅에 이미지가 있으면 이미지를 리사이징한다. pillow에 있는 resize와 구분하기 위해 rescale이라고 함수명을 지어줬다.

 

def rescale(image, width):
    img = pil.open(image)

    src_width, src_height = img.size
    src_ratio = float(src_height) / float(src_width)
    dst_height = round(src_ratio * width)

    img = img.resize((width, dst_height), pil.LANCZOS)
    img.save(image.name, 'PNG')
    image.file = img
    
    # 이게 없으면 attribute error 발생
    image.file.name = image.name

    return image

인자로 이미지 파일image과 고정시키려는 너비width를 받는다.

너비만 고정시키고 높이는 원본의 비율을 따를거기 때문에

원본의 비율을 구해줬다. src_ratio

그리고 변환할 높이dst_height를 구해서 (pillow resize가 int로만 인자를 받기 때문에) 반올림해줬다. 

이제 이미지를 resize해주고, 필터는 LANCZOS를 사용했다. (몇가지 필터가 있지만 pillow공식문서에서 가장 기본적으로 추천하는 필터)

alpha가 담긴 이미지들도 있기 때문에 PNG포맷으로 저장해주고, 기존의 이미지파일의 파일image.file을 리사이징된 이미지로 바꿔주었다.

*여기까지만 하고 장고 서버를 실행시켜보면 attribute 'name'을 찾을 수 없다는 에러가 발생한다.
저장할 때 파일 이름이 필요한데, 우리가 새롭게 만든 pillow이미지 파일에는 파일이름이 없기 때문에 발생하는 오류다. 

따라서 기존 이미지의 이름을 파일 이름으로 지정해주는 과정(image.file.name = image.name)이 필요하다.

반응형
Comments