PIL基礎操作


PIL基礎操作

新建圖片

from PIL import Image

# 通常使用RGB模式就可以了
new_img = Image.new('RGB', (100, 100), 'red')
new_img.save("1.jpg", "JPEG")

new_img = Image.new('RGB', (100, 100), '#B286FF')
new_img.save("2.jpg", "JPEG")

new_img = Image.new('RGB', (100, 100), (255, 255, 128))
new_img.save("3.jpg", "JPEG")

打開圖片

BASE_PATH = os.path.dirname(os.path.abspath(__file__))

file_path = os.path.join(BASE_PATH, "fj.jpg")

# 打開圖片
img = Image.open(file_path)

"""
format : 識別圖像的源格式,如果該文件不是從文件中讀取的,則被置為 None 值。
size : 返回的一個元組,有兩個元素,其值為象素意義上的寬和高。
mode : 
· 1 (1-bit pixels, black and white, stored with one pixel per byte)
· L (8-bit pixels, black and white)
· P (8-bit pixels, mapped to any other mode using a colour palette)
· RGB (3x8-bit pixels, true colour)
· RGBA (4x8-bit pixels, true colour with transparency mask)
· CMYK (4x8-bit pixels, colour separation)
· YCbCr (3x8-bit pixels, colour video format)
· I (32-bit signed integer pixels)
· F (32-bit floating point pixels)
"""

print img.format, img.size, img.mode, img.height, img.width
# h,w = img.size    # (X,Y)
等價於
# h = img.heigth
# w = img.width

# 縮略圖
img.thumbnail((w*0.75, h//2))
img.save("1.jpg", "JPEG")

# 應用模糊濾鏡:
im2 = img.filter(ImageFilter.BLUR)
# 存儲圖片 im2.save('blur.jpg', 'JPEG')
• BLUR:模糊濾波
• CONTOUR:輪廓濾波
• DETAIL:細節濾波
• EDGE_ENHANCE:邊界增強濾波
• EDGE_ENHANCE_MORE:邊界增強濾波(程度更深)
• EMBOSS:浮雕濾波
• FIND_EDGES:尋找邊界濾波
• SMOOTH:平滑濾波
• SMOOTH_MORE:平滑濾波(程度更深)
• SHARPEN:銳化濾波
• GaussianBlur(radius=2):高斯模糊
>radius指定平滑半徑。
• UnsharpMask(radius=2, percent=150, threshold=3):反銳化掩碼濾波
>radius指定模糊半徑;
>percent指定反銳化強度(百分比);
>threshold控制被銳化的最小亮度變化。
• Kernel(size, kernel, scale=None, offset=0):核濾波
當前版本只支持核大小為3x3和5x5的核大小,且圖像格式為“L”和“RGB”的圖像。
>size指定核大小(width, height);
>kernel指定核權值的序列;
>scale指定縮放因子;
>offset指定偏移量,如果使用,則將該值加到縮放后的結果上。
• RankFilter(size, rank):排序濾波
>size指定濾波核的大小;
>rank指定選取排在第rank位的像素,若大小為0,則為最小值濾波;若大小為size * size / 2則為中值濾波;若大小為size *
size - 1則為最大值濾波。
• MedianFilter(size=3):中值濾波
>size指定核的大小
• MinFilter(size=3):最小值濾波器
>size指定核的大小
• MaxFilter(size=3):最大值濾波器
>size指定核的大小
• ModeFilter(size=3):波形濾波器
選取核內出現頻次最高的像素值作為該點像素值,僅出現一次或兩次的像素將被忽略,若沒有像素出現兩次以上,則保留原像素值。
>size指定核的大小
ImageFilter類預定義濾波

 裁切圖片

在這個副本上的任何操作不會影響到原圖像

# 接收元組(X,Y,X,Y)
cp_img = img.crop((0, 100, 30, 300))
cp_img.save("cp.jpg", "JPEG")

 復制圖片

# 剪切
# cp_img = img.crop((0, 0, 450, 300))
# 復制
cp_img = img.copy()
# 新建圖片
new_img = Image.new("RGB", (500, 300), (255, 255, 255))
# 在新建的圖片上粘貼裁剪的圖片
# new_img.paste(cp_img)
# 指定起始坐標(左上角)
new_img.paste(cp_img, (50, 0))
new_img.save("cp_img.jpg", "JPEG")

 調整圖片大小

resize不是等比例縮放的

w,d = img. size
# 只接受整數
new_img = img.resize((500, 350))
new_img.save("1.jpg", "JPEG")

旋轉圖片

# 90度
img.rotate(90).save("rotate90.jpg", "JPEG")
# 180度
img.rotate(180).save("rotate180.jpg", "JPEG")
# 270度
img.rotate(270).save("rotate270.jpg", "JPEG")
# 20度
img.rotate(20).save("rotate20.jpg", "JPEG")
# 放大旋轉20度,expand放大了圖像尺寸,使得邊角的圖像不被裁剪四個角剛好貼着圖像邊緣)
img.rotate(20, expand=True).save("20.jpg", "JPEG")
# 圖像的鏡面翻轉(必須傳入Image.FLIP_LEFT_RIGHT(水平翻轉)/Image.FLIP_TOP_BOTTOM(垂直翻轉))
img.transpose(Image.FLIP_LEFT_RIGHT).save("tran_img.jpg", "JPEG")   # 水平翻轉
img.transpose(Image.FLIP_TOP_BOTTOM).save("tran_img_.jpg", "JPEG")   # 垂直翻轉

畫圖(ImageDraw)

導入包

from PIL import ImageDraw
from PIL import Image

直線

# 新建畫板
im_board = Image.new("RGB", (500, 500), (255, 255, 255))
# 創建畫筆(所有畫的動作都是由此對象生成的)
drawObject = ImageDraw.Draw(im_board)

# 起始xy,結束xy[x,y,x,y]    fill直線顏色    width直線寬度
drawObject.line([150, 50, 350, 50], fill=10, width=5)
drawObject.line([(150, 250), 350, 250], fill=128)
drawObject.line([(150, 50), (150, 250)], "black")
drawObject.line((350, 50, 350, 250), fill="yellow")

 效果:

# fill顏色為將圓填充色, outline邊界顏色
drawObject.arc((150, 200, 300, 350), 0, 360, fill="black")
drawObject.arc((150, 220, 300, 350), 180, 360, fill="red")
drawObject.arc((150, 230, 300, 350), 180, 270, fill="red")
drawObject.arc((150, 235, 300, 350), 270, 180, fill="red")
drawObject.arc((150, 240, 300, 350), 180, 270, fill="red")
drawObject.arc((150, 245, 300, 350), 270, 180, fill="red")

# fill顏色為將圓填充色, outline邊界顏色
# drawObject.ellipse((150, 200, 300, 350), fill="blue", outline=128)

 效果:

 

# 用法與arc相同,用來畫圓從startAngle到endAngle的弦
# Options選項中fill表示將弦與圓弧之間空間用指定顏色填滿,outlie表示只規定弦線的顏色
# drawObject.chord([x1, y1, x2, y2],  startAngle,  endAngle,  options)

# 畫圓
drawObject.ellipse((100, 100, 300, 300), outline=128)

# 畫弦並且將弦與弧包圍區域塗色
drawObject.chord((100, 100, 300, 300), 0, 360, fill="yellow")

# 畫一條弦
drawObject.chord((100, 100, 300, 300), 0, 180, outline="blue")
drawObject.chord((100, 100, 300, 300), 0, 135, outline="blue")
drawObject.chord((100, 100, 300, 300), 135, 270, outline="blue")
drawObject.chord((100, 100, 300, 300), 270, 45, outline="blue")
drawObject.chord((100, 100, 300, 300), 45, 180, outline="blue")

 效果:

扇區

# options選項中fill選項將扇形區域用指定顏色填滿,outline選項只用指定顏色描出區域輪廓
# drawObject.pieslice([x1,y1,x2,y2],  startAngle,  endAngle,  options)
# 畫一個圓
drawObject.ellipse((100, 100, 300, 300), outline=128)
# 畫180度到210度的扇形區域輪廓
drawObject.pieslice((100, 100, 300, 300), 0, 45, outline=128)
drawObject.pieslice((100, 100, 300, 300), 180, 235, outline=128)

# 畫60度到90度的扇形區域
drawObject.pieslice((100, 100, 300, 300), 0, 90, fill="blue")
drawObject.pieslice((100, 100, 300, 300), 180, 270, fill="blue")

 效果:

多邊形

# 根據第一個參量中的xy坐標對,連接出整個圖形
# options選項中fill選項將多邊形區域用指定顏色填滿,outline選項只用指定顏色描出區域輪廓
# drawObject.polygon(([x1,y1,x2,y2,…],options)
#                    第一點坐標  第二點坐標    第三點坐標    連接線的顏色
drawObject.polygon([(50, 300), (200, 300), (50, 100)], outline="red")
drawObject.polygon([(50, 100), (300, 100), (50, 300), (300, 300)], fill="red", outline="blue")
drawObject.polygon([(50, 100), (50, 300), (300, 100), (300, 300)], fill="blue", outline="red")

 效果:

 

矩形

# (x1,y1)表示矩形左上角坐標值,(x2,y2)表示矩形右下角坐標值
# options選項中fill選項將多邊形區域用指定顏色填滿,outline選項只用指定顏色描出區域輪廓
# drawObject.rectangle([x1,y1,x2,y2],options)drawObject
drawObject.rectangle((100, 100, 300, 300), outline="red")
drawObject.rectangle((100, 300, 300, 320), fill=128)

 效果:

添加文字

# Position是一個二元元組,指定字符串左上角坐標,string是要寫入的字符串
# options選項可以為fill或者font(只能選擇其中之一作為第三參量.
# 不能兩個同同時存在,要改變字體顏色,見ImageFont模塊
# text = u"人生苦短,我用派生"
text = u"I Love You"
drawObject.text([100, 200], text, "red")

 效果:

 字

 在圖片中寫字

from PIL import ImageDraw, ImageFont
from PIL import Image

hwxw_path = os.path.join(BASE_PATH, "font", "華文新魏.ttf")
hwxk_path = os.path.join(BASE_PATH, "font", "華文行楷.ttf")
hwls_path = os.path.join(BASE_PATH, "font", "華文隸書.ttf")
# 新建畫板
im_board = Image.new("RGB", (500, 500), (255, 255, 255))
# 畫筆對象
drawObject = ImageDraw.Draw(im_board)
# 定義字體  ImageFont.truetype(file,size)
# 創建一個字體對象.這個函數從指定的文件加載了一個字體對象,並且為指定字體大小
hwxw_font = ImageFont.truetype(hwxw_path, 18)
hwxk_font = ImageFont.truetype(hwxk_path, 24)
hwls_font = ImageFont.truetype(hwls_path, 36)
"""
注意事項:筆的默認顏色為白色,畫筆的顏色可以通過draw的ink屬性來改變
draw.ink = 0(R) + 0(G) * 256 + 0(B) * 256 * 256
也可以通過fill參數更改字體顏色
"""

drawObject.rectangle([100, 100, 400, 400], outline=128)

text = u"人生苦短"
text_ = u"我用"
text__ = u"Python"
# 利用text函數添加文字
# drawObject.ink = 0 + 0 * 256 + 0 * 256 * 256
drawObject.text([180, 170], text, font=hwxw_font, fill="yellow")
# drawObject.ink = 0 + 128 + 100
drawObject.text([180, 200], text_, font=hwxk_font, fill="blue")
# drawObject.ink = 0 + 0 * 256 + 255 * 256 * 256
drawObject.text([180, 230], text__, font=hwls_font, fill=(255, 222, 111))


im_board.save("drawing_board.png", "PNG")

# Font.getsize(text)
# 返回一個二元素元組,為指定text在指定字體大小之后的size
print hwxk_font.getsize(text)

 生成驗證碼(借鑒):

import Image, ImageDraw, ImageFont, ImageFilter
import random


hwxw_path = os.path.join(BASE_PATH, "font", "華文新魏.ttf")
hwxk_path = os.path.join(BASE_PATH, "font", "華文行楷.ttf")
hwls_path = os.path.join(BASE_PATH, "font", "華文隸書.ttf")
font_list = [hwxw_path, hwxk_path, hwls_path]

# 隨機字母:
def rndChar():
    return chr(random.randint(65, 90))

# 隨機顏色1:
def rndColor():
    return (random.randint(64, 255), random.randint(64, 255), random.randint(64, 255))

# 隨機顏色2:
def rndColor2():
    return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127))

# 240 x 60:
width = 60 * 4
height = 60
image = Image.new('RGB', (width, height), (255, 255, 255))
# 創建Font對象:
font = ImageFont.truetype(random.choice(font_list), 36)
# 創建Draw對象:
draw = ImageDraw.Draw(image)
# 填充每個像素:
for x in range(width):
    for y in range(height):
        draw.point((x, y), fill=rndColor())
# 輸出文字:
for t in range(4):
    draw.text((60 * t + 10, 10), rndChar(), font=font, fill=rndColor2())
# 模糊:
image = image.filter(ImageFilter.BLUR)
image.save('code.jpg', 'jpeg')

Pillow只是個基礎的圖像處理庫,OpenCV是更好的選擇

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM