❤️【Python從入門到精通】(二十七)更進一步的瞭解Pillow吧!

碼農飛哥發表於2021-10-18

您好,我是碼農飛哥,感謝您閱讀本文,歡迎一鍵三連哦
進一步介紹Pillow庫的使用,詳細瞭解
乾貨滿滿,建議收藏,需要用到時常看看。 小夥伴們如有問題及需要,歡迎踴躍留言哦~ ~ ~。

前言

本文是接上一篇❤️【Python從入門到精通】(二十六)用Python的PIL庫(Pillow)處理影像真的得心應手❤️ 進一步介紹Pillow庫的使用,本文將重點介紹一些高階特性:比如如何利用Pillow畫圖形(圓形,正方形),介紹通過Pillow庫給圖片新增水印;同時對上一篇文章未介紹的常用知識點進行補充說明。希望對讀者朋友們有所幫助。

Image模組

上一篇文章已經介紹了Image模組,但是介紹的還不夠全面,例如如何從網頁中讀取圖片沒有介紹到,如何裁剪圖片都沒有介紹到。

讀取網頁中的圖片

讀取網頁中的圖片的基本實現方式是:首先利用requests庫讀取當前圖片連結的內容,接著將內容轉成二進位制資料,在通過open方法將該二進位制資料,最後通過save方法進行儲存。

from PIL import Image
from io import BytesIO
import requests
# 讀取網頁圖片
res = requests.get(
    'https://img-blog.csdnimg.cn/f2e98e08d5ec4283b08972c5ee8e1689.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA56CB5Yac6aOe5ZOl,size_20,color_FFFFFF,t_70,g_se,x_16').content
#將圖片內容轉成二進位制
im2 = Image.open(BytesIO(res))
b = BytesIO()
im2.save(b, format='PNG')
im2.show()

讀取結果是:
在這裡插入圖片描述

圖片裁剪

通過crop方法可以從圖片中裁剪出一個指定大小的區域。裁取的區域範圍是(left, upper, right, lower) 比如從某個寬高都是400的圖片中裁剪一個是寬高都是100的正方形區域,只需要指定裁剪區域的座標是: (0, 0, 100, 100)

im2 = Image.new('RGBA', (400, 400), 'blue')
box = (0, 0, 100, 100)
region = im2.crop(box)  # 設定要裁剪的區域
region.show()

有裁剪還有一個方法就是重新設定圖片大小的方法 resize,比如將前面400400的圖片 修改成 300200,只需要呼叫resize方法

img4 = im2.resize((300, 200))
img4.show()

圖片模式的說明:

模式 描述
1 1位畫素,黑白影像,存成8位畫素
L 8位畫素,黑白
P 8位畫素,使用調色盤對映到任何其他模式
RGB 3*8位畫素,真彩
RGBA 4*8 位畫素,真彩+透明通道
CMYK 4*8位畫素,印刷四色模式或彩色印刷模式
YCbCr 3*8位畫素,色彩視訊格式
I 32位整型畫素
F 33位浮點型畫素

通過 convert方法進行圖片模式的轉換

ImageDraw模組

前面介紹的ImageDraw庫,只是介紹了利用它來向圖片寫入文字,其實ImageDraw模組還有一個更有用的途徑,就是可以通過它來畫各種圖形。

畫圖的方法介紹

方法 示範 作用
ImageDraw.line(xy, fill=None, width=0, joint=None) draw.line([100, 100, 100, 500], fill='blue', width=2) 畫正方形
ImageDraw.arc(xy, start, end, fill=None, width=1) draw.arc([100, 100, 600, 600], 0, 360, fill='black') 畫弧形
ImageDraw.ellipse(xy, fill=None, outline=None, width=1) draw.ellipse([100, 100, 600, 600], outline='black', fill='white') 畫圓
ImageDraw.chord(xy, start, end, fill=None, outline=None, width=1) draw.chord([100, 100, 600, 600], 0, 360, outline=125) 畫半圓,類似於arc()
ImageDraw.pieslice(xy, start, end, fill=None, outline=None, width=1) draw.pieslice([100, 100, 600, 600], 180, 210, outline=255) 畫扇形
ImageDraw.rectangle(xy, fill=None, outline=None, width=1) draw.rectangle((200, 200, 500, 500), outline='yellow') 畫矩形
ImageDraw.rounded_rectangle(xy, radius=0, fill=None, outline=None, width=1) draw.rounded_rectangle((200, 200, 600, 600), radius=1, outline='green') 畫圓角矩形(或正方形)

畫正方形

首先建立一個600*600的畫布。然後再畫布中畫出一個正方形,畫直線的方法是 line方法。
ImageDraw.line(xy, fill=None, width=0, joint=None)

在xy的座標之間畫一條直線
xy--> 在兩個座標點之間畫一條直線,座標點的傳入方式是[(x, y), (x, y), ...]或者[x, y, x, y, ...]
fill--> 直線的顏色
width--> 直線的寬度

# 畫點
im = Image.new('RGB', (600, 600), 'white')
draw = ImageDraw.Draw(im)

# # 建立一個正方形,fill 代表的為顏色
draw.line([100, 100, 100, 500], fill='blue', width=2)  # 左豎線
draw.line([100, 100, 500, 100], fill='blue', width=2)  # 上橫線
draw.line([500, 100, 500, 500], 'blue', width=2) #右豎線
draw.line([100, 500, 500, 500], 'blue', width=2) #下橫線
im.save('picture/sequare.png', 'png')
im.show()

畫一個邊框寬度為2px,顏色為藍色的,面積為400*400的正方形。
在這裡插入圖片描述

畫弧形

ImageDraw.arc(xy, start, end, fill=None, width=0)

在給定的區域範圍內,從開始角到結束角之間繪製一條圓弧
xy--> 定義邊界框的兩個點,傳入的格式是[(x0, y0), (x1, y1)] 或者 [x0, y0, x1, y1] ,其中 x1>=x0,y1>=y0
start --> 起始角度,以度為單位,從3點鐘開始順時針增加
end--> 結束角度,以度為單位
fill--> 弧線的顏色
width-->弧線的寬度

draw.arc([100, 100, 600, 600], 0, 180, fill='black')
im.show()

在這裡插入圖片描述
這裡就是畫了一個半圓,如果結束角度是360度的話則就會畫一個完整的圓。

畫圓

畫圓通過ImageDraw.ellipse(xy, fill=None, outline=None, width=1) 方法,該方法可以畫出一個給定範圍的圓

xy--> 定義邊界框的兩個點,傳入的格式是[(x0, y0), (x1, y1)] 或者 [x0, y0, x1, y1] ,其中 x1>=x0,y1>=y0
outline--> 輪廓的顏色
fill ---> 填充顏色
width--> 輪廓的寬度

draw.ellipse([100, 100, 600, 600], outline='black', fill='blue')
im.show()

在這裡插入圖片描述

畫半圓

ImageDraw.chord(xy, start, end, fill=None, outline=None, width=1) 方法用來畫半圓,跟arc()方法不同的是它會用直線將起始點和結束點連線起來

xy--> 定義邊界框的兩個點,傳入的格式是[(x0, y0), (x1, y1)] 或者 [x0, y0, x1, y1] ,其中 x1>=x0,y1>=y0
outline--> 輪廓的顏色
fill ---> 填充顏色
width--> 輪廓的寬度

draw.chord([100, 100, 600, 600], 0, 180,  outline='black', fill='red')
im.show()

在這裡插入圖片描述

畫扇形

ImageDraw.pieslice(xy, start, end, fill=None, outline=None, width=1)
類似於arc()方法,不過他會在端點和圓點之間畫直線
xy--> 定義邊界框的兩個點,傳入的格式是[(x0, y0), (x1, y1)] 或者 [x0, y0, x1, y1] ,其中 x1>=x0,y1>=y0
start --> 起始角度,以度為單位,從3點鐘開始順時針增加
end--> 結束角度,以度為單位
fill--> 弧線的顏色
width-->弧線的寬度

draw.pieslice([100, 100, 600, 600], 180, 300, outline='red', fill='blue')
im.show()

在這裡插入圖片描述

畫矩形

ImageDraw.rectangle(xy, fill=None, outline=None, width=1)
xy--> 在兩個座標點之間畫一條直線,座標點的傳入方式是[(x, y), (x, y), ...]或者[x, y, x, y, ...]
outline--> 輪廓的顏色
fill--> 填充的顏色
width--> 輪廓線的寬度

# 矩形
draw.rectangle((100, 200, 300, 500), outline='red', fill='blue')
im.show()

在這裡插入圖片描述

畫圓角矩形

ImageDraw.rounded_rectangle(xy, radius=0, fill=None, outline=None, width=1) 該方法可以畫一個圓角矩形
xy--> 在兩個座標點之間畫一條直線,座標點的傳入方式是[(x, y), (x, y), ...]或者[x, y, x, y, ...]
radius--> 角的半徑
outline--> 輪廓的顏色
fill--> 填充的顏色
width--> 輪廓線的寬度

draw.rounded_rectangle((200, 200, 600, 600), radius=2, outline='green')
im.show()

在這裡插入圖片描述

解決一個問題

這裡有個問題,就是畫好的圖形如何從Image中扣出來呢?

ImageEnhance模組

ImageEnhance模組主要是用於設定圖片的顏色對比度亮度銳度等啥的,增強影像。

  1. 原圖
from PIL import ImageEnhance, Image

org_img = Image.open('picture/img10.png')
org_img.show(title='原圖')

原始影像
在這裡插入圖片描述

  1. 影像的顏色平衡,顏色增強1.2倍
    PIL.ImageEnhance.Color(image) 方法,這個方法主要用於調整影像的色彩平衡,原始影像的係數是1.0,0.0的增強係數得到的是一個黑白影像
cl = ImageEnhance.Color(org_img)
#黑白影像
ce = cl.enhance(0)
ce.show()
#增強1.2倍
ce1 = cl.enhance(1.2)
ce1.show()

在這裡插入圖片描述

  1. 調整影像的對比度 3:4
    PIL.ImageEnhance.Contrast(image)該方法主要用於調整影像的對比度,類似於電視機上的對比度控制,0.0的增強係數給出的是一個純灰色影像,係數1.0則得到原始影像
ct = ImageEnhance.Contrast(org_img)
ch = ct.enhance(0)
ch.show(title='對比度0純灰色')
ch1 = ct.enhance(3.4)
ch1.show(title='對比度3.4')

在這裡插入圖片描述
7. 調整影像的亮度
PIL.ImageEnhance.Brightness(image) ,該方法主要用於調整影像的亮度,0.0的增強係數表示黑色影像。係數為1.0則得到原始影像。

br = ImageEnhance.Brightness(org_img)
be = br.enhance(0)
be.show(title='亮度0')
be = br.enhance(3)
be.show(title='亮度3')

在這裡插入圖片描述

  1. 調整影像的銳度
    PIL.ImageEnhance.Sharpness(image) ,該方法主要用於調整影像的銳度,0.0的增強因子為模糊影像,1.0的增強因子為原始影像,2.0的增強因子為銳化影像。
sp = ImageEnhance.Sharpness(org_img)
se = sp.enhance(0)
se.show(title='銳度0')
se1 = sp.enhance(20)
se1.show(title='銳度20')

在這裡插入圖片描述

ImageFilter模組

ImageFilter模組主要用於對影像進行過濾,增強邊緣,模糊處理,該模組的使用方式是im.filter(ImageFilter)
其中ImageFilter按照需求傳入指定的過濾值。

過濾值 作用
ImageFilter.GaussianBlur 高斯模糊
ImageFilter.BLUR 普通模糊
ImageFilter.EDGE_ENHANCE 邊緣增強
ImageFilter.FIND_EDGES 找到邊緣
ImageFilter.EMBOSS 浮雕
ImageFilter.CONTOUR 輪廓
ImageFilter.SHARPEN 銳化

下面一個個試下效果

  1. 原圖
from PIL import Image, ImageFilter
im = Image.open('picture/img10.png')
im.show()

在這裡插入圖片描述
2. 高斯模糊

im1 = im.filter(ImageFilter.GaussianBlur)
im1.show()

在這裡插入圖片描述
3. 普通模糊

im2 = im.filter(ImageFilter.BLUR)
im2.show()

在這裡插入圖片描述
4.邊緣增強

im3 = im.filter(ImageFilter.EDGE_ENHANCE)
im3.show()

在這裡插入圖片描述
5. 找到邊緣

im4 = im.filter(ImageFilter.FIND_EDGES)
im4.show()

在這裡插入圖片描述
6. 浮雕

im5 = im.filter(ImageFilter.EMBOSS)
im5.show()

在這裡插入圖片描述
7. 輪廓

im6 = im.filter(ImageFilter.CONTOUR)
im6.show()

在這裡插入圖片描述
8. 銳化

im7 = im.filter(ImageFilter.SHARPEN)
im7.show()

在這裡插入圖片描述

ImageGrab模組

ImageGrab模組主要用於對螢幕進行截圖,通過grab方法進行擷取,如果不傳入任何引數則表示全螢幕截圖,否則是擷取指定區域的影像。其中box格式是:(x1,x2,y1,y2)

from PIL import ImageGrab
im1 = ImageGrab.grab((0, 0, 600, 300))  # 擷取螢幕600*300的區域的影像
im2 = ImageGrab.grab()  # 不帶參數列示全螢幕截圖
im1.show()
im2.show()

在這裡插入圖片描述

利用Pillow庫對影像增加水印

利用Pillow庫可以輕易的對影像增加水印
首先,用PIL的Image函式讀取圖片
接著,新建一張圖(尺寸和原圖一樣)
然後,在新建的圖象上用PIL的ImageDraw把字給畫上去,字的顏色從原圖處獲取。

from PIL import Image, ImageDraw, ImageFont

font_size = 8
text = "泳池美女"

img_raw = Image.open("../picture/beautiful.jpeg")
# 1.讀取影像,獲取每一個畫素值
img_array = img_raw.load()
# 2. 新建畫布,選好要使用的字型大小
new_img = Image.new('RGB', img_raw.size, 'gray')
font = ImageFont.truetype("../picture/simsun.ttf", size=font_size)
draw = ImageDraw.Draw(new_img)


# 搞一個生成器(不斷迴圈"泳池美女")
def character_generate(text):
    while True:
        for i in range(len(text)):
            yield text[i]


char_gen = character_generate(text)
# 實現效果
for y in range(0, img_raw.size[1], font_size):
    for x in range(0, img_raw.size[0], font_size):
        draw.text((x + 1, y + 1), next(char_gen), font=font, fill=img_array[x, y])

new_img.convert('RGB').save("../picture/beautiful_result.jpeg")

原圖
在這裡插入圖片描述
新增文字後的效果圖

在這裡插入圖片描述

總結

本文詳細介紹了Pillow庫的使用,希望對讀者朋友們有所幫助。

參考

Pillow官方文件

原始碼獲取

需要獲取原始碼的小夥伴可以關注下方的公眾號,回覆【python】

我是碼農飛哥,再次感謝您讀完本文
全網同名【碼農飛哥】。不積跬步,無以至千里,享受分享的快樂
我是碼農飛哥,再次感謝您讀完本文

相關文章