osError: cannot write mode RGBA as JPEG
JPEG 확장자를 갖는 이미지는 투명도(A)를 표현할 수 없는 RGB파일이다.
따라서, RGBA 이미지를 RGB 이미지로 변환시켜줘야 한다.
if main_img.mode == "RGBA":
# RGBA 이미지를 JPEG으로 저장 불가하므로
main_img = main_img.convert("RGB")
import os
import django
from datetime import datetime
from PIL import Image, ImageFont, ImageDraw, ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
from io import BytesIO
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings")
django.setup()
from django.core.files import File
from core.models import *
# 이미지 폴더 경로
IMG_FOLDER_PATH = os.getcwd() + "/image_files/"
# 워터마크 적용
def paste_watermark(local_main_image, main_width, main_height):
"""
1000 by 1000 인 경우 워터마크 적용 헬퍼함수
"""
padding_right = 12
padding_bottom = 16
text = "쿠돈에서 직접 촬영한 사진입니다"
PWD = os.getcwd() + "/core/management/Spoqa Han Sans Regular.ttf"
font = ImageFont.truetype(PWD, 24)
text_width, text_height = font.getsize(text)
watermark = Image.new('RGBA', (text_width, text_height), 0) # 투명 배경 생성
draw = ImageDraw.Draw(watermark)
draw.text((0, 0), text=text, fill=(153, 153, 153, 85), font=font) # 투명 배경에 워터마크 반영
# 메인 배경 우측 하단에 워터마크 paste
local_main_image.paste(
watermark,
(main_width - text_width - padding_right,
main_height - text_height - padding_bottom),
mask=watermark)
main_img = local_main_image.convert("RGB")
# 워터마크 적용된 이미지 리턴
return main_img
# 이미지 업로더
def local_image_download():
"""
로컬 이미지를 DB로 업로드
"""
image_cnt = 1
img_file_list = []
product_code_list = Product.objects.filter(id__gt=454).values_list("product_code", flat=True)
last_index = ProductImage.objects.last().id
cur_idx = last_index + 1
total_file_list = []
for img_name in os.listdir(IMG_FOLDER_PATH):
if ".DS_Store" in img_name:
continue
product_code = img_name.split("_")[0]
if product_code in product_code_list:
product = Product.objects.get(product_code=product_code)
main_img = Image.open(IMG_FOLDER_PATH + img_name)
main_width, main_height = main_img.size
if main_width <= 500 or main_height <= 500: # 500 이하 이미지는 버린다.
continue
if (main_width == main_height == 1000): # 워터마크 적용 조건
main_img = paste_watermark(main_img, main_width, main_height)
# 장고 ImageField에 저장
new_filename = f"{product_code}_{image_cnt}.jpg" # 새롭게 저장할 이미지 이름
image_io = BytesIO() # BytesIO object 생성
# RGBA 이미지의 경우, RGB 이미지로 변환
if main_img.mode == "RGBA":
# RGBA 이미지를 JPEG으로 저장 불가하므로
main_img = main_img.convert("RGB")
main_img.save(image_io, 'JPEG') # 로컬 이미지를 BytesIO object로 저장
product_image = File(image_io, name=new_filename) # create a django friendly File object
temp_dict = {
"id": cur_idx,
"product_image": product_image,
"product_id": product.id
}
img_file_list.append(temp_dict)
cur_idx += 1
image_cnt += 1
# bulk_create
bulk_items= [ProductImage(id=i["id"], image_url=i['product_image'], product_id=i["product_id"]) for i in img_file_list]
ProductImage.objects.bulk_create(bulk_items)
start_time = datetime.now()
print(start_time)
# 업로드 시작
local_image_download()
end_time = datetime.now()
print(end_time)
gap = end_time - start_time
print(gap)
# 24 분 소요