end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

Pillow & numpy for python による画像処理

メモ。詳細は、python script内のコメントをご覧ください

# coding: utf-8

from PIL import Image
import numpy as np

def main():
    img_file_path = "./marble.png"
    img = Image.open(img_file_path)
    
    change_color_mode( img )    # カラー/モノクロモード変換
    get_set_color( img )        # カラー参照/設定
    get_img_size( img )         # サイズ情報
    resize_img( img )           #   〃  変更
    rotate_img( img )           # 回転
    paste_img( img )            # 貼り付け

    make_new_img()              # 画像の新規作成
    from_to_bytes( img )        # 画像<->byte列変換
    from_to_numpy( img )        # 画像<->byte列変換 (numpy版)

def from_to_numpy( img ):
    img_numpy = np.array( img )
    print( img_numpy.size, img_numpy.shape )

    new_img = Image.fromarray(img_numpy)
    new_img.show()
    
def from_to_bytes( img ):
    img_size = img.size
    print( img_size[0] * img_size[1] * 3 )
    # byte列へ
    img_bytes = img.tobytes()
    print( len( img_bytes ) )
    
    # byte列から画像へ
    new_img = Image.frombytes("RGB",img_size, img_bytes)
    new_img.show()

    
def make_new_img():
    # 単一色
    colors = bytes( [176,224,230]*256*256 )
    new_img = Image.frombytes(
        "RGB", # L:グレースケール、RGB:カラー
        (256,256),
        colors )
    new_img.show()
    
    # グラデーション
    colors_ba = bytearray( [255]*256*256*3 )
    for i in range(1, len(colors_ba), 3):
        colors_ba[i] = (i // 3) % 256
    new_img = Image.frombytes(
        "RGB", # L:グレースケール、RGB:カラー
        (256,256),
        bytes(colors_ba) )
    new_img.show()

def get_set_color( img ):
    for x in range( 0, img.height ):
        for y in range( 0, img.width ):
            pixel = img.getpixel( (x,y) )
            print( pixel )
            #img.putpixel((x,y),(pixel[2],pixel[1],pixel[0]) )
    
def rotate_img( img ):
    new_img = img.rotate(30)
    new_img.show()
    
    new_img = img.rotate(
        -30,
        expand=True,
        center   =(0, 60),      # 回転中心
        translate=(50,50),      # 平行移動
        fillcolor=(255, 128, 0),# 外側の色
        # NEAREST(default),BICUBIC(細部きれい)
        resample=Image.Resampling.BICUBIC
    )
    new_img.show()
    
def resize_img( img ):
    # trim
    trim_coodrs = (50,50,150,150) # 左端, 上端, 右端, 下端
    new_img = img.crop( trim_coodrs )
    new_img.show()
    
    # 拡大/縮小
    new_img = img.resize( (150,150) )
    new_img.show()

    new_img = img.resize(
        (150,150),
        # NEAREST(default),LANCZOS(きれい)
        resample=Image.Resampling.LANCZOS
    )
    new_img.show()
    
    
def get_img_size( img ):
    print(img.height, img.width, img.size ) # W, H, (W,H)
    
    print(np.array( img ).shape ) # W x H x Channel by numpy

def change_color_mode( img ):
    color_modes = [["1","1_bit_pixels"],        # 白黒
                   ["L","8-bit-grayscale"],     #   〃
                   ["P","8-bit-colors"]]        # カラー
    
    for color_mode in color_modes:
        new_img = img.convert( color_mode[0] )
        # new_img.save(color_mode[0] +".png")
        new_img.show()

if __name__ == '__main__':
    main()