Pythonの画像処理ライブラリPillow(PIL)で特定のサイズ以上の画像をサイズ変更

目次

Pillow(PIL)

前回、Pythonの画像処理ライブラリPillow(PIL)を使って、iPhone、MacBook Air、iPad miniのスクリーンショットをトリミングした後、サイズ変更するプログラムを解説しました。

ここまではどれも規定値のサイズがあり、そこから一定量トリミングし、特定のサイズへサイズ変更をしてきました。

しかしもう一つ、Macでは「shift + command + 4」で特定の領域だけスクリーンショットを撮ることもできます。

その場合、画像のサイズはまちまちです。

そうした時、私は横のサイズを1000ピクセルとなるように処理してから、ブログにアップしています。

ただし1000ピクセルよりも小さい場合は処理をせず使用しています。

ということで今回は縦か横のサイズが設定値より大きい場合のみ、サイズ変更をするという部分を組み込んでいきましょう。

プログラム全体

<セル1>

import os
from PIL import Image

newname = "test_"

iPhone_fix_size = [0, 100, 0, 0, 1000, 0] #[left, upper, right, lower, width, height] width&height 0 = keep ratio
MBAir_fix_size = [0, 290, 0, 0, 1000, 0]
iPadmini_fix_size = [0, 40, 0, 0, 1000, 0]
other_fix_size = [0, 0, 0, 0, 1000, 0]

default_path =""

iPhone_ss_size = [1125, 2436]
MBAir_ss_size = [3104, 1834]
iPadmini_ss_size = [1536, 2048]

ext_list = [".png", ".PNG"]
<セル2>

def path_set(default_path):
    if default_path == "":
        path_temp = os.getcwd()
    else:
        path_temp = default_path
    return path_temp

def file_select(default_path, newname, ext_list):
    list_temp = []
    for file in os.listdir(default_path):
        if file[-4:] in ext_list:
            if not newname in file:
                list_temp.append(file)
    return list_temp
            
def trimming(im, fix_size):
    width = im.size[0]
    height = im.size[1]
    im_trim = im.crop((fix_size[0], fix_size[1], width - fix_size[2], height - fix_size[3]))
    return im_trim

def resizing(im, fix_size):
    width = im.size[0]
    height = im.size[1]
    resize_width = fix_size[4]
    resize_height = fix_size[5]
    
    resized = im
    
    if resize_width == 0 and resize_height == 0:
        print("ERROR: resize_size should not be [0, 0]")
    elif resize_height == 0:
        if width > resize_width:
            resized = im.resize((resize_width, int(height/(width/resize_width))))
    elif resize_width == 0:
        if height > resize_height:
            resized = im.resize((int(width/(height/resize_height)), resize_height))
    elif resize_size[0] != 0 and resize_size[1] != 0:
        if width > resize_width and height > resize_height:
            resized = im.resize((resize_width, resize_height))
        
    return resized
    
<セル3>

if __name__ == '__main__':
    default_path = path_set(default_path)
    file_list = sorted(file_select(default_path, newname, ext_list))
    
    os.chdir(default_path)

    i = 1
    filling = len(str(len(file_list))) + 1
    
    for file in file_list:
        im = Image.open(file)
        if im.size[0] == iPhone_ss_size[0] and im.size[1] == iPhone_ss_size[1]:
            im_trim = trimming(im, iPhone_fix_size)
            im_trim_resize = resizing(im_trim, iPhone_fix_size)
            im_trim_resize.save(newname + str(i).zfill(filling) + ".png")
        elif im.size[0] == MBAir_ss_size[0] and im.size[1] == MBAir_ss_size[1]:
            im_trim = trimming(im, MBAir_fix_size)
            im_trim_resize = resizing(im_trim, MBAir_fix_size)
            im_trim_resize.save(newname + str(i).zfill(filling) + ".png")       
        elif im.size[0] == iPadmini_ss_size[0] and im.size[1] == iPadmini_ss_size[1]:
            im_trim = trimming(im, iPadmini_fix_size)
            im_trim_resize = resizing(im_trim, iPadmini_fix_size)
            im_trim_resize.save(newname + str(i).zfill(filling) + ".png") 
        else:
            im_resize = resizing(im, other_fix_size)
            im_resize.save(newname + str(i).zfill(filling) + ".png") 
        i = i + 1

<セル1>の変更点

<セル1>での変更点は、iPhone、MacBook Air、iPad miniのそれぞれのサイズに当てはまらない画像の処理を書いたこの部分の追加です。

other_fix_size = [0, 0, 0, 0, 1000, 0]

これまでの書式通り[左、上、右、下、幅、縦]の順番になっています。

ですがスクリーンショットを撮った時点で特定の範囲となっているため、トリミングは必要ないと考えられますので、最初の4つは「0」となっています。

<セル2>の変更点

<セル2>の変更点は幅、縦の長さで分岐処理しているこの部分です。

   resized = im
    
    if resize_width == 0 and resize_height == 0:
        print("ERROR: resize_size should not be [0, 0]")
    elif resize_height == 0:
        if width > resize_width:
            resized = im.resize((resize_width, int(height/(width/resize_width))))
    elif resize_width == 0:
        if height > resize_height:
            resized = im.resize((int(width/(height/resize_height)), resize_height))
    elif resize_size[0] != 0 and resize_size[1] != 0:
        if width > resize_width and height > resize_height:
            resized = im.resize((resize_width, resize_height))

例えば横幅を規定してサイズ変更する場合のこの部分では、「if width > resize_width:」が挿入されています。

elif resize_height == 0:
        if width > resize_width:
            resized = im.resize((resize_width, int(height/(width/resize_width))))

これにより処理する前の画像の横幅が、処理後の横幅よりも小さい場合はこの後の処理を行わないようにしています。

縦を規定してサイズ変更をする場合の分岐と両方を規定する場合の分岐においても、処理前の画像のサイズが小さい場合は処理しないようにしています。

  elif resize_width == 0:
        if height > resize_height:
            resized = im.resize((int(width/(height/resize_height)), resize_height))
    elif resize_size[0] != 0 and resize_size[1] != 0:
        if width > resize_width and height > resize_height:
            resized = im.resize((resize_width, resize_height))

ただこのような分岐にすると、画像が小さい場合はどの処理も行われない、つまり変数resizedが定義されない状況が生まれてしまいます。

そのため最初に「resized = im」と元の画像を変数resizedに代入しておくことにより、画像が小さい場合はそのまま返すプログラムにしています。

<セル3>の変更点

<セル3>の変更点はiPhone、MacBook Air、iPad miniのどれにも当てはまらない場合「else:」を追加し、その中に関数resizingをする処理を加えています。

        else:
            im_resize = resizing(im, other_fix_size)
            im_resize.save(newname + str(i).zfill(filling) + ".png") 

ということで、これでめでたく完成しました。

プログラムの実行結果

今回は大小二つのスクリーンショットを用意してみました。

最初の画像のサイズは1996 x 1270ピクセル。

2番目の画像のサイズは564 x 212 ピクセル。

この場合だと最初の画像だけ処理されて、2番目の画像は処理されないはずです。

試してみた結果がこちらです。

サイズを確認してみると、最初の画像は1000 x 636 ピクセルに縮小されています。

2番目の画像は最初と同じく564 x 212 ピクセルのままです。

ということで思った通りの動作が確認できました。

これで今後ブログの画像処理がだいぶ楽になる…はずです。

またバグとかあれば対処して記事にしていきたいと思います。

ではでは今回はこんな感じで。

よかったらシェアしてね!

コメント

コメントする

目次
閉じる