您好,我是碼農飛哥,感謝您閱讀本文,歡迎一鍵三連哦。
進一步介紹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模組主要是用於設定圖片的顏色對比度亮度銳度等啥的,增強影像。
- 原圖
from PIL import ImageEnhance, Image
org_img = Image.open('picture/img10.png')
org_img.show(title='原圖')
原始影像
- 影像的顏色平衡,顏色增強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()
- 調整影像的對比度 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')
- 調整影像的銳度
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 | 銳化 |
下面一個個試下效果
- 原圖
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庫的使用,希望對讀者朋友們有所幫助。
參考
原始碼獲取
需要獲取原始碼的小夥伴可以關注下方的公眾號,回覆【python】
我是碼農飛哥,再次感謝您讀完本文。
全網同名【碼農飛哥】。不積跬步,無以至千里,享受分享的快樂
我是碼農飛哥,再次感謝您讀完本文。