[파이썬 업무자동화] 05.이미지크기를 간편하게 줄여보자!

2019. 7. 29. 08:30Development/Hacking With Python

Youtube 영상

링크
깃헙 소스코드 링크

Q: 누구한테 필요할까요?

A:

앱 개발자 : 디자이너에게 이미지를 받았는데 이미지 크기가 5mb네? 앱은 20mb인데...ㅠㅠ
디자이너 : 간편하게 여러 이미지들을 한번에 변환하고 싶다! 근데 포토샵 없으면 아무것도 모르겠다...ㅠㅠ
서버 개발자 : 프로필 사진 하나에 10mb씩 들어가네.. 클라우드 스토리지 비용도 더 들고.. 트래픽도 느려! ㅠㅠ
일반인 : 꿀뷰도 편하지만.. 인생은 짧고 파이썬은 빠르니까 한번 해보자!

좋아요와 많은 구독 부탁드립니다 ^^

소스코드

import os
import sys
from PIL import Image
from conf import image_config
import ntpath
import argparse


def optimize_in_dir(file_names, img_dir_path):
    for i in range(len(file_names)):
        print('{0}.{1}'.format(i+1, file_names[i]))
        try:
            resize_img(img_dir_path+file_names[i], image_config["max_dimension"])
        except Exception as e:
            print('Error => ', e)


def get_all_file_path(cwd):
    img_dir_path = cwd + '/' + image_config["origin_img_dir_path"]
    print('img_dir_path => ', img_dir_path)
    file_names = []

    # check extension
    for file_name in os.listdir(img_dir_path):
        ext = os.path.splitext(file_name)[1].lower()
        support_exts = ['.bmp','.gif','.png','.tiff','.jpeg','.jpg']
        if ext in support_exts:
            file_names.append(file_name)

    print('Bellow images will be optimize!!!')
    print(file_names)
    optimize_in_dir(file_names, img_dir_path)



def save_optimized_img(img_path, picture, ratio):
    width, height = (picture.size)
    picture.thumbnail((width*ratio,height*ratio), Image.ANTIALIAS)

    # following optimize_into_jpg option! => force convert to jpg
    if image_config["optimize_into_jpg"] == True:
        picture = picture.convert('RGB')
        file_name = ntpath.basename(img_path)
        new_name = os.path.splitext(file_name)[0]+'.jpg'
        print('optimizing...', img_path)
        try:
            picture.save(image_config["optimized_img_dir_path"] + new_name,"JPEG", optimize=True, quality=quality)
            print('Success !!!')
        except Exception as e:
            print('error => ', e)
    else:
        print('optimizing...', img_path)
        try:
            picture.save(image_config["optimized_img_dir_path"] + ntpath.basename(img_path), optimize=True, quality=quality)
        except Exception as e:
            print('error => ', e)


def resize_img(img_path, max_dimension):
    picture = Image.open(img_path)
    width, height = (picture.size)
    if width > height :
        longger_size = width
    else:
        longger_size = height
    ratio = max_dimension / longger_size
    save_optimized_img(img_path, picture, ratio)


def init_conf():
    cwd = os.path.dirname(os.path.realpath(__file__))
    quality = image_config["quality"]
    max_dimension = image_config["max_dimension"]
    return cwd, quality, max_dimension


class MyParser(argparse.ArgumentParser):
    def error(self, message):
        sys.stderr.write('error: %s\n' % message)
        self.print_help()
        sys.exit(2)


def init_parser():
    help = '''Specific Image file path to convert. \nBasically, If do not use it, \n[./img/*] images will be optimized in [./img-optimized]\nor change conf.py
    '''
    parser = MyParser(formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument('-f', required=False, help=help)

    if len(sys.argv) == 1:
        return None
    elif len(sys.argv) > 3 :
        parser.print_help(sys.stderr)
        sys.exit(1)

    args = parser.parse_args()
    img_path = args.f
    return img_path


if __name__ == "__main__":
    img_path = init_parser()
    cwd, quality, max_dimension = init_conf()
    print(cwd, quality, max_dimension)

    # convert all images in img directory
    if img_path == None:
        get_all_file_path(cwd)

    # convert specific image
    else:
        print('Target => ', img_path)
        try:
            resize_img(img_path, image_config["max_dimension"])
        except Exception as e:
            print('Error => ', e)
    input('Press any key...')