본문 바로가기
IT CHANNEL/Python

[Django] webp ,바이트 스트림(Byte Stream) 개념과 이미지 webp 형식으로 변환하기

by TitanX 2023. 9. 1.

 

webp라는 파일이 어떤 것 인지 최근에 알게되어 프로젝트를 진행하며 사용했던 개념을 기록한다

메인페이지에서 이미지를 여러개 뿌려주는 부분이 있다.

고품질의 PNG이미지를 여러개 사용하다보니 로딩하는데 살짝 버벅이는 느낌이 있었다.(아주 미세하지만 로딩이 느린 것 같음)

진행하던 프로젝트 기획 상 특정 페이지의 이미지 파일 업로드는 백오피스에서만 이뤄지고 다운로드는 하지 않기 때문에 파일 용량을 낮추는 것이 좋다고 생각했다. 이미지 포맷 중 하나인 webp는 고품질의 이미지를 상대적으로 작은 파일 크기로 저장할 수 있다.

이 글에서는 업로드된 이미지를 업로드(저장)할 때 webp포맷으로 자동 변환했던 것을 기록한다.

 

 

webp 변환을 위한 Pillow 라이브러리 설치

pip install Pillow django

 

webp 변환 예제코드

from django.db import models
from django.core.files.uploadedfile import InMemoryUploadedFile
from PIL import Image
import io

class MyModel(models.Model):
    image = models.ImageField(upload_to='images/')

    def save(self, *args, **kwargs):
        image_temporary = Image.open(self.image) #디스크에서 이미지를 읽어온다. 그리고 **io.BytesIO()**를 통해 메모리 상에서 이미지를 처리한다.
        output_io_stream = io.BytesIO() # 메모리 상에서 바이트 스트림을 생성해준다. 이 스트림은 이미지 데이터를 임시로 저장하는 버퍼 역할로 작동한다.

        if image_temporary.format != 'WEBP':
            image_temporary.convert('RGB').save(output_io_stream, format='WEBP')# WebP로 변환하고, 이를 스트림에 저장한다.
            output_io_stream.seek(0)
            self.image = InMemoryUploadedFile(
                output_io_stream,
                'ImageField',
                f"{self.image.name.split('.')[0]}.webp",
                'image/webp',
                output_io_stream.getbuffer().nbytes,
                None
            )# 메모리 상의 이미지 데이터를 Django 모델에 저장할 수 있는 형태의 객체로 생성한다.
        super().save(*args, **kwargs)

 

 

바이트 스트림(Byte Stream)

 

 

바이트 단위로 구성된 데이터의 연속적인 흐름이다.

스트림은 데이터에 대해 순차적 읽기/쓰기 구조를 가지며, 바이트 스트림은 이런 데이터 흐름이 바이트 단위로 이루어진다는 것을 특징으로 한다

 

특징

 

  1. 바이너리 데이터 처리: 바이트 스트림은 텍스트 데이터뿐만 아니라 이미지, 오디오, 비디오 등의 바이너리 데이터도 처리할 수 있다.
  2. 순차적 접근: 스트림은 데이터를 순차적으로 읽고 쓰므로, 대용량 데이터를 효율적으로 처리할 수 있다.
  3. 버퍼링: 스트림은 일반적으로 버퍼(buffer)를 사용하여 데이터를 임시로 저장하고, 이를 통해 I/O 성능을 향상한다.
  4. Python에서의 바이트 스트림 : 바이트 스트림을 io.BytesIO 클래스를 통해 메모리 상에서 다룰 수 있다. 메모리 상에서도 파일을 다루는 것처럼 스트림을 읽고 쓸 수 있다.

 

 

결과

3.2MB 의 png 형식 이미지를 업로드 하여 47.7 KB로 줄어든 webp 형식으로 변경되었다.