Python画像処理のPillow 26選

# はじめに
Pythonの画像処理Pillowについてまとめる。

https://pypi.org/project/pillow/

![simple_animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/5bb90bf8-0bec-ef14-7ee8-786626980e3f.gif)

# Pillow 26選 
No.|処理内容|定義
---|-------|----
①|読み込み|Image.open('sample.jpg')
②|画像情報を取得する|image.format<br>image.size<br>image.mode<br>image.info
③|表示する|image.show()
④|コピーする|image.copy()
⑤|保存する|image.save('ファイル名')
⑥|明るさを変える|image.point(lambda i: i * ```明るさ```)
⑦|回転する|image.rotate(```角度```)
⑧|反転する|上下：ImageOps.flip(image)<br>左右：ImageOps.mirror(image)
⑨|白黒にする|image.convert("L")
⑩|2値ドット絵にする|image.convert("1")
⑪|色反転する|ImageOps.invert(image)
⑫|エンボス加工する|image.filter(ImageFilter.EMBOSS)
⑬|輪郭を抽出する|image.filter(ImageFilter.FIND_EDGES)
⑭|サイズ変更する|image.resize((```幅,高さ```))
⑮|サムネイルにする|image.thumbnail((128, 128))
⑯|切り抜きする|image.crop(```left```, ```upper```, ```right```, ```lower```)
⑰|サイズに合わせて黒でパディングする|長い辺に合わせて正方形にして黒色でパディングする場合<br>ImageOps.pad(image, (max(image.size),max(image.size)), color=(0,0,0))
⑱|余白切り抜きする|色を反転してから切り抜き<br>image.crop(ImageOps.invert(image).getbbox())
⑲|ぼかす|image.filter(ImageFilter.BLUR)
⑳|モザイクを入れる|小さくして(例は1/10)、戻す<br>image.resize((image.size[0]//10,image.size[1]//10)).resize(image.size, resample=Image.NEAREST)<br>image.resize((image.size[0]//10,image.size[1]//10)).resize(image.size, resample=Image.BILINEAR)
㉑|クリップボードの映像を取得する|image=ImageGrab.grabclipboard()
㉒|描画・文字を入れる|キャンバス:draw = ImageDraw.Draw(canvas)<br>四角:draw.rectangle()<br>三角:draw.polygon()<br>円:draw.ellipse()<br>線:draw.line()<br>文字:draw.text()
㉓|画像を張り付ける|image.paste()
㉔|透過させる|image.putalpha(alpha=50)
㉕|アルファブレンドする|Image.blend(img_1, img_2, 0.5)
㉖|画像結合してgifにしてアニメーションにする|gif_frames[0].save("gif_anime.gif", save_all=True, append_images=gif_frames[1:], duration=1000, loop=0)

```python:sample.py
from PIL import Image, ImageFilter, ImageOps, ImageGrab, ImageDraw, ImageFont


# ①読み込み------------------------------------------------------------
image = Image.open('sample.jpg')

# ②画像情報を取得する--------------------------------------------------
print(f'{image.format=} {image.size=} {image.mode=}{image.info=}')

# ③表示する------------------------------------------------------------
image.show()

# ④コピーする----------------------------------------------------------
image_copy = image.copy()

# ⑤保存する------------------------------------------------------------
image_copy.save('05_image_copy.jpg')

# ⑥明るさを変える------------------------------------------------------
# 明るく
image_bright = image.point(lambda i: i * 2.0)
image_bright.save('06_image_bright.jpg')
# 暗く
image_dark = image.point(lambda i: i * 0.5)
image_dark.save('06_image_dark.jpg')

# ⑦回転する------------------------------------------------------------
# 90°回転
image_90 = image.rotate(90)
image_90.save('07_image_90.jpg')
# 45°回転
image_45 = image.rotate(45)
image_45.save('07_image_45.jpg')
# 45°回転 サイズ拡張
image_45expand = image.rotate(45, expand=True)
image_45expand.save('07_image_45expand.jpg')

# ⑧反転する------------------------------------------------------------
# 上下反転
image_flip = ImageOps.flip(image)
image_flip.save('08_image_flip.jpg')
# 左右反転
image_mirror = ImageOps.mirror(image)
image_mirror.save('08_image_mirror.jpg')

# ⑨白黒にする----------------------------------------------------------
image_bw = image.convert("L")
image_bw.save('09_image_bw.jpg')

# ⑩2値ドット絵にする---------------------------------------------------
image_dot = image.convert("1")
image_dot.save('10_image_dot.jpg')

# ⑪色反転する----------------------------------------------------------
# 色反転はRGBで実施必要(RGBA不可)
image_inverted = ImageOps.invert(image)
image_inverted.save('11_image_inverted.jpg')

# ⑫エンボス加工する----------------------------------------------------
image_emboss = image.filter(ImageFilter.EMBOSS)
image_emboss.save('12_image_emboss.jpg')


# ⑬輪郭を抽出する------------------------------------------------------
image_edge = image.filter(ImageFilter.FIND_EDGES)
image_edge.save('13_image_edge.jpg')

# ⑭サイズ変更する------------------------------------------------------
image_resized = image.resize((128,64))
image_resized.save('14_image_resized.jpg')

# ⑮サムネイルにする----------------------------------------------------
# (縦横比保持してサイズ変更 copy()しないと元のデータ変更される)
image_tumbnail = image.copy()
image_tumbnail.thumbnail((128, 128))
image_tumbnail.save('15_image_tumbnail.jpg')

# ⑯切り抜きする--------------------------------------------------------
# 切り抜き(corp(left, upper, right, lower)) 左上1/4切り抜き
image_cut1 = image.crop((0,0,image.size[0]//2,image.size[1]//2))
image_cut1.save('16_image_cut1.jpg')

# 切り抜き(corp(left, upper, right, lower)) 中心から100
image_cut2 = image.crop((image.size[0]//2-100,image.size[1]//2-100, image.size[0]//2+100, image.size[1]//2+100))
image_cut2.save('16_image_cut2.jpg')

# ⑰サイズに合わせて黒でパディングする----------------------------------
# 長い辺に合わせて正方形にして、パディング
image_pad = ImageOps.pad(image, (max(image.size),max(image.size)), color=(0,0,0))
image_pad.save('17_image_pad.jpg')

# ⑱余白切り抜きする----------------------------------------------------
# 色を反転させて切り抜き
image_blankcut = image.crop(ImageOps.invert(image).getbbox())
image_blankcut.save('18_image_blankcut.jpg')

# ⑲ぼかす--------------------------------------------------------------
image_blur = image_blankcut.filter(ImageFilter.BLUR)
image_blur.save('19_image_blur.jpg')

# ⑳モザイクを入れる----------------------------------------------------
# サイズを1/10にして元のサイズに引き伸ばし
image_mosaic1 = image_blankcut.resize((image_blankcut.size[0]//10,image_blankcut.size[1]//10)).resize(image_blankcut.size, resample=Image.NEAREST)
image_mosaic1.save('20_image_mosaic1.jpg')
image_mosaic2 = image_blankcut.resize((image_blankcut.size[0]//10,image_blankcut.size[1]//10)).resize(image_blankcut.size, resample=Image.BILINEAR)
image_mosaic2.save('20_image_mosaic2.jpg')

# ㉑クリップボードの映像を取得する--------------------------------------
image_clip=ImageGrab.grabclipboard()
if(image_clip!=None):
    image_clip.save('21_image_clip.png')

# ㉒描画・文字を入れる--------------------------------------------------
canvas = Image.new("RGB", (512, 512), (200, 200, 200))
draw = ImageDraw.Draw(canvas)
# 四角 (x始点,y始点,x終点,y終点) fill=色 outline=枠色
draw.rectangle((0, 0, 100, 100), fill=(0, 255, 0), outline=(0,200,0))
# 三角 (1点,2点,3点) fill=色 outline=枠色
draw.polygon(((200, 200), (400, 200), (300, 100)), fill=(255, 0, 0), outline=(200,0,0))
# 円 (x始点,y始点,x終点,y終点) fill=色 outline=枠色
draw.ellipse((300, 300, 500, 500), fill=(0, 0, 255), outline=(0,0,200))
# 線 (x始点,y始点,x終点,y終点) fill=色 width=太さ
draw.line((250, 250, 0, 500), fill=(0, 0, 0), width=10)
# 文字 (x始点,y始点) fill=色 font_size=サイズ font= ImageFont.truetype(フォントパス,サイズ) 
# font指定 フォントの場所とサイズ
draw.text((75, 50), 'テキスト', fill=(0, 0, 0), align='center',font = ImageFont.truetype('C:\Windows\Fonts\meiryo.ttc',100) )
canvas.save('22_canvas.jpg')

# ㉓画像を張り付ける----------------------------------------------------
image_paste = image.copy()
image_paste.paste(canvas,(image.size[0]//2,0))
image_paste.save('23_image_paste.jpg')

# ㉔透過させる----------------------------------------------------------
# alpha:透過度0～255
# 透過はRBGAなので、JPEGでは保存できないためpngで保存
image_alpha = image.copy()
image_alpha.putalpha(alpha=50)
image_alpha.save('24_image_alpha.png')

# ㉕アルファブレンドする------------------------------------------------
#pngに変換してサイズを合わせる
Image.open('sample.jpg').save('25_sample.png')
alpha_1 = Image.open('25_sample.png')
Image.open('22_canvas.jpg').resize(alpha_1.size).save('25_canvas.png')
alpha_2 = Image.open('25_canvas.png')

image_blend = Image.blend(alpha_1, alpha_2, 0.5)
image_blend.save('25_image_blend.png')


# ㉖画像結合してgifにしてアニメーションにする---------------------------
gif_frames=[
image,
image_copy,
image_bright,
image_dark,
image_90,
image_45,
image_45expand,
image_flip,
image_mirror,
image_bw,
image_dot,
image_inverted,
image_emboss,
image_edge,
image_resized,
image_tumbnail,
image_cut1,
image_cut2,
image_pad,
image_blankcut,
image_blur,
image_mosaic1,
image_mosaic2,
canvas,
image_paste,
image_alpha,
image_blend,]

# サイズを1枚目に合わせる。
for cnt in range(len(gif_frames)):
	gif_frames[cnt]=gif_frames[cnt].resize(gif_frames[0].size)

# append_images:次のページ,duration:表示時間(ms),loop:ループ回数0は無限
gif_frames[0].save("simple_animation.gif", save_all=True, append_images=gif_frames[1:], duration=1000, loop=0)
```