Python Pillow庫詳細介紹與代碼示例
一、Pillow 庫簡介
- 功能:圖像打開/保存、尺寸調(diào)整、濾鏡應(yīng)用、顏色處理、繪圖、文字添加等
- 支持格式:JPEG, PNG, GIF, BMP, TIFF 等 30+ 格式
- 核心模塊:Image, ImageDraw, ImageFilter, ImageEnhance 等
二、安裝 Pillow
pip install Pillow
三、核心功能及代碼示例
1. 打開/保存圖像
from PIL import Image # 打開圖像 img = Image.open("input.jpg") print(f"格式: {img.format}, 尺寸: {img.size}, 模式: {img.mode}") # 保存圖像(自動識別格式) img.save("output.png") # 轉(zhuǎn)換格式 img.save("converted.webp", "WEBP")
2. 基本圖像操作
# 調(diào)整尺寸 resized = img.resize((300, 200)) # 旋轉(zhuǎn)(expand參數(shù)防止裁剪) rotated = img.rotate(45, expand=True) # 裁剪 (left, upper, right, lower) cropped = img.crop((100, 100, 400, 400)) # 縮略圖生成(保持比例) img.thumbnail((128, 128)) img.save("thumbnail.jpg")
3. 圖像處理
from PIL import ImageFilter, ImageEnhance # 應(yīng)用濾鏡 blurred = img.filter(ImageFilter.GaussianBlur(radius=2)) contour = img.filter(ImageFilter.CONTOUR) # 顏色調(diào)整 gray = img.convert("L") # 轉(zhuǎn)為灰度 enhancer = ImageEnhance.Contrast(img) contrast_img = enhancer.enhance(2.0) # 對比度增強2倍 # 調(diào)整亮度 bright_enhancer = ImageEnhance.Brightness(img) bright_img = bright_enhancer.enhance(1.5)
4. 繪制圖形和文字
from PIL import ImageDraw, ImageFont # 創(chuàng)建新畫布 canvas = Image.new("RGB", (500, 500), color=(255, 255, 255)) draw = ImageDraw.Draw(canvas) # 繪制形狀 draw.rectangle([50, 50, 200, 200], fill="red", outline="blue") draw.ellipse([250, 250, 400, 400], fill="yellow") # 添加文字 try: font = ImageFont.truetype("arial.ttf", 24) except IOError: font = ImageFont.load_default() draw.text((100, 300), "Hello Pillow!", fill="black", font=font) canvas.show()
5. 高級操作
# 圖像合成 overlay = Image.new("RGBA", img.size, (255, 0, 0, 100)) composite = Image.alpha_composite(img.convert("RGBA"), overlay) # 像素級操作 pixels = img.load() for y in range(img.height): for x in range(img.width): r, g, b = pixels[x, y] pixels[x, y] = (r//2, g//2, b//2) # 暗化效果 # 創(chuàng)建 GIF images = [img, rotated, cropped] images[0].save("animation.gif", save_all=True, append_images=images[1:], duration=500, loop=0)
四、綜合應(yīng)用示例:添加水印
def add_watermark(input_path, output_path, text): base = Image.open(input_path).convert("RGBA") txt = Image.new("RGBA", base.size, (255,255,255,0)) draw = ImageDraw.Draw(txt) font = ImageFont.truetype("arial.ttf", 36) # 計算文字位置 text_width, text_height = draw.textsize(text, font) x = base.width - text_width - 10 y = base.height - text_height - 10 draw.text((x, y), text, font=font, fill=(255,255,255,128)) combined = Image.alpha_composite(base, txt) combined.convert("RGB").save(output_path) add_watermark("photo.jpg", "watermarked.jpg", "? Your Brand")
五、注意事項
- 處理透明通道時使用
RGBA
模式 - JPEG 格式不支持透明度,保存時需轉(zhuǎn)換模式
- 大尺寸圖像處理需注意內(nèi)存消耗
- 使用
with
語句管理文件資源:
with Image.open("large_image.tiff") as img: # 處理圖像
六、典型應(yīng)用場景
- 批量生成縮略圖
- 為圖片添加版權(quán)信息
- 圖像格式轉(zhuǎn)換工具
- 創(chuàng)建動態(tài)驗證碼圖片
- 圖像數(shù)據(jù)增強(機器學(xué)習(xí))
七、高級圖像處理技巧
1. 通道操作與混合
from PIL import Image, ImageChops # 分離 RGB 通道 r, g, b = img.split() # 合并時調(diào)整通道順序(例如創(chuàng)建偽紅外效果) modified = Image.merge("RGB", (b, g, r)) # 通道混合(數(shù)學(xué)運算) diff = ImageChops.difference(img1, img2) # 像素差異圖 blended = ImageChops.blend(img1, img2, alpha=0.3) # 圖像疊加
2. 顏色空間轉(zhuǎn)換
# CMYK 轉(zhuǎn) RGB cmyk_img = Image.open("cmyk_image.tiff").convert("RGB") # 轉(zhuǎn)換為 HSV 顏色空間(需使用第三方庫補充) # 注意:Pillow 原生不支持 HSV 操作,但可通過 numpy 實現(xiàn) import numpy as np hsv_array = np.array(img.convert("HSV")) # ...處理 HSV 數(shù)組... modified_img = Image.fromarray(hsv_array, "HSV").convert("RGB")
3. EXIF 元數(shù)據(jù)處理
# 讀取 EXIF 數(shù)據(jù) exif_data = img._getexif() if exif_data: from PIL.ExifTags import TAGS for tag_id, value in exif_data.items(): tag_name = TAGS.get(tag_id, tag_id) print(f"{tag_name}: {value}") # 旋轉(zhuǎn)圖像(根據(jù) EXIF 方向信息自動修正) from PIL import ImageOps fixed_img = ImageOps.exif_transpose(img)
八、性能優(yōu)化技巧
1. 大圖處理方案
# 分塊處理大圖 tile_size = 512 for y in range(0, img.height, tile_size): for x in range(0, img.width, tile_size): box = (x, y, x+tile_size, y+tile_size) tile = img.crop(box) # 處理分塊... img.paste(tile, box)
2. 使用內(nèi)存優(yōu)化模式
# 使用 LA 模式替代 RGBA(節(jié)省 25% 內(nèi)存) gray_alpha = img.convert("LA")
3. 加速像素操作
# 使用 numpy 加速像素處理 import numpy as np arr = np.array(img) arr = arr // 2 # 快速暗化處理 fast_processed = Image.fromarray(arr)
九、實戰(zhàn)項目示例
1. 生成驗證碼圖片
from PIL import Image, ImageDraw, ImageFont, ImageFilter import random def generate_captcha(text, size=(200, 80)): img = Image.new("RGB", size, (255,255,255)) draw = ImageDraw.Draw(img) # 繪制干擾線 for _ in range(8): start = (random.randint(0, size[0]), random.randint(0, size[1])) end = (random.randint(0, size[0]), random.randint(0, size[1])) draw.line([start, end], fill=(random.randint(0,255), random.randint(0,255), random.randint(0,255)), width=2) # 添加文字 font = ImageFont.truetype("arial.ttf", 36) text_width, text_height = draw.textbbox((0,0), text, font=font)[2:] x = (size[0] - text_width) / 2 y = (size[1] - text_height) / 2 # 文字扭曲 for i, char in enumerate(text): draw.text( (x + i*30 + random.randint(-5,5), y + random.randint(-5,5)), char, font=font, fill=(random.randint(0,160), random.randint(0,160), random.randint(0,160)) ) # 添加濾鏡 img = img.filter(ImageFilter.SMOOTH_MORE) return img captcha = generate_captcha("3A4B") captcha.save("captcha.jpg")
2. 批量圖片處理器
import os from PIL import Image, ImageOps def batch_process(input_dir, output_dir, process_func): os.makedirs(output_dir, exist_ok=True) for filename in os.listdir(input_dir): if filename.lower().split('.')[-1] not in ['jpg', 'png', 'jpeg']: continue with Image.open(os.path.join(input_dir, filename)) as img: processed = process_func(img) processed.save(os.path.join(output_dir, filename)) # 示例處理函數(shù):轉(zhuǎn)換為素描風(fēng)格 def sketch_effect(img): gray = img.convert("L") invert = ImageOps.invert(gray) blur = invert.filter(ImageFilter.GaussianBlur(3)) return ImageChops.dodge(gray, blur) batch_process("./photos", "./processed", sketch_effect)
十、圖像分析功能
1. 直方圖分析
histogram = img.histogram() # 獲取 R 通道直方圖(前256個值) red_hist = histogram[:256] # 繪制簡易直方圖(需 matplotlib) import matplotlib.pyplot as plt plt.figure(figsize=(10,4)) plt.title("Red Channel Histogram") plt.bar(range(256), red_hist, color='red') plt.show()
2. 邊緣檢測
from PIL import ImageFilter edges = img.convert("L").filter(ImageFilter.FIND_EDGES) edges = edges.point(lambda x: 255 if x > 50 else 0) # 二值化 edges.show()
十一、錯誤處理與調(diào)試
1. 健壯的圖像處理
try: with Image.open("problematic.jpg") as img: # 處理圖像... except IOError as e: print(f"無法打開圖像文件: {str(e)}") except Image.DecompressionBombError: print("圖像尺寸過大,請檢查是否安全!")
2. 內(nèi)存管理技巧
# 強制釋放圖像內(nèi)存 img.close() # 顯式關(guān)閉 # 使用 with 語句自動管理 with Image.open("large_image.tiff") as img: thumbnail = img.copy() thumbnail.thumbnail((1024, 1024)) thumbnail.save("small.jpg") # 注意:此時原圖已關(guān)閉
十二、與其他庫集成
1. 結(jié)合 OpenCV 使用
import cv2 import numpy as np from PIL import Image # Pillow -> OpenCV pil_img = Image.open("demo.jpg") cv_img = np.array(pil_img.convert('RGB'))[:, :, ::-1] # RGB to BGR # OpenCV -> Pillow cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB) pil_img = Image.fromarray(cv_img)
2. 結(jié)合 Matplotlib 顯示
import matplotlib.pyplot as plt plt.imshow(img) plt.axis('off') plt.title("Pillow Image Display") plt.show()
十三、擴展知識
1. 自定義濾鏡
from PIL import ImageFilter class CustomFilter(ImageFilter.BuiltinFilter): name = "CustomSharpen" filterargs = (3, 3), 16, 0, ( -1, -1, -1, -1, 24, -1, -1, -1, -1 ) sharpened = img.filter(CustomFilter())
2. 插件圖像格式支持
# 安裝額外解碼器后,可支持 WebP 動畫等 # 需安裝:pip install pillow-heif import pillow_heif heif_file = pillow_heif.open_heif("image.heif") heif_img = Image.frombytes( heif_file.mode, heif_file.size, heif_file.data, "raw", heif_file.mode, heif_file.stride, )
十四、最佳實踐建議
格式選擇策略
- 網(wǎng)頁使用:
JPEG
(照片)、PNG
(透明/圖標)、WEBP
(現(xiàn)代格式) - 打印使用:
TIFF
(無損)、PDF
(矢量) - 動態(tài)圖片:
GIF
(簡單動畫)、APNG
(高質(zhì)量動畫)
- 網(wǎng)頁使用:
質(zhì)量參數(shù)優(yōu)化
img.save("optimized.jpg", quality=85, # 質(zhì)量值 (1-100) optimize=True, # 啟用優(yōu)化 progressive=True) # 漸進式JPEG
- 多幀圖像處理(GIF/TIFF)
with Image.open("animation.gif") as img: for frame in ImageSequence.Iterator(img): # 處理每一幀 frame.save(f"frame_{frame.tell()}.png")
十五、高級圖像分析技術(shù)
1. 直方圖匹配(色調(diào)映射)
import numpy as np from PIL import Image def histogram_matching(source, template): """ 將源圖像的直方圖匹配到模板圖像 """ src = np.array(source.convert('L')).flatten() tgt = np.array(template.convert('L')).flatten() # 計算累積分布函數(shù) src_vals, src_counts = np.unique(src, return_counts=True) tgt_vals, tgt_counts = np.unique(tgt, return_counts=True) src_cdf = np.cumsum(src_counts) / src.size tgt_cdf = np.cumsum(tgt_counts) / tgt.size # 創(chuàng)建映射表 lut = np.interp(src_cdf, tgt_cdf, tgt_vals) return source.point(lut) source_img = Image.open("landscape.jpg") template_img = Image.open("sunset.jpg") matched = histogram_matching(source_img, template_img)
2. 圖像分割(閾值處理)
from PIL import ImageOps # Otsu 自動閾值算法 gray = img.convert('L') thresh = gray.point(lambda x: 255 if x > 130 else 0) # 手動閾值 # 自動閾值(需要 scikit-image) from skimage.filters import threshold_otsu arr = np.array(gray) thresh_val = threshold_otsu(arr) auto_thresh = Image.fromarray((arr > thresh_val).astype(np.uint8) * 255)
十六、專業(yè)領(lǐng)域應(yīng)用
1. 醫(yī)學(xué)影像處理(DICOM)
# 需要安裝 pydicom import pydicom from PIL import Image ds = pydicom.dcmread("MRI.dcm") arr = ds.pixel_array.astype(float) arr = (arr - arr.min()) / (arr.max() - arr.min()) * 255 medical_img = Image.fromarray(arr.astype(np.uint8)) medical_img.save("mri_preview.png")
2. 衛(wèi)星圖像處理(多光譜分析)
# 加載多波段圖像 with Image.open("satellite.tif") as img: bands = [img.getchannel(band) for band in ('R', 'G', 'B', 'NIR')] # 計算 NDVI(歸一化植被指數(shù)) red = np.array(bands[0], dtype=np.float32) nir = np.array(bands[3], dtype=np.float32) ndvi = (nir - red) / (nir + red + 1e-10) # 防止除以零 # 可視化 NDVI ndvi_img = Image.fromarray(np.uint8((ndvi + 1) * 127.5)) ndvi_img.save("ndvi_map.png")
十七、三維圖像處理
1. Z-Stack 圖像合成
import glob from PIL import Image, ImageMath # 加載聚焦堆棧圖像 z_images = [Image.open(f) for f in sorted(glob.glob("z_stack_*.tif"))] # 創(chuàng)建全聚焦圖像 def focus_metric(pixels): return np.std(pixels) # 使用標準差作為清晰度指標 depth_map = np.zeros(z_images[0].size[::-1]) final_img = np.zeros_like(np.array(z_images[0])) for i in range(z_images[0].height): for j in range(z_images[0].width): pixels = [np.array(img)[i,j] for img in z_images] sharpness = [focus_metric(p) for p in pixels] best_idx = np.argmax(sharpness) final_img[i,j] = pixels[best_idx] depth_map[i,j] = best_idx Image.fromarray(final_img).save("focused.tif") Image.fromarray(np.uint8(depth_map * 255 / len(z_images))).save("depth_map.png")
十八、GPU加速處理
1. 使用 CUDA 加速(需安裝 cupy)
import cupy as cp from PIL import Image def gpu_filter(img): # 轉(zhuǎn)換到 GPU img_gpu = cp.asarray(img) # 自定義核函數(shù)(邊緣檢測) kernel = cp.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], dtype=cp.float32) # 卷積運算 filtered = cp.zeros_like(img_gpu) for c in range(3): filtered[:, :, c] = cp.convolve2d(img_gpu[:, :, c], kernel, mode='same') # 返回 CPU return Image.fromarray(cp.asnumpy(filtered).astype(np.uint8)) original = Image.open("gpu_demo.jpg") accelerated = gpu_filter(original)
十九、與深度學(xué)習(xí)框架集成
1. PyTorch 數(shù)據(jù)增強管道
from torchvision import transforms from PIL import Image class AdvancedAugmentation: def __init__(self): self.transform = transforms.Compose([ transforms.RandomApply([ lambda x: transforms.functional.adjust_sharpness(x, 2), lambda x: ImageEnhance.Color(x).enhance(0.8) ], p=0.5), transforms.RandomPerspective(distortion_scale=0.3), transforms.ColorJitter(brightness=0.2, contrast=0.2) ]) def __call__(self, img): return self.transform(img) augmenter = AdvancedAugmentation() img = Image.open("training_sample.jpg") augmented = augmenter(img)
二十、插件開發(fā)與擴展
1. 自定義圖像格式解碼器
from PIL import Image, ImageFile class RAWDecoder(ImageFile.PyDecoder): def decode(self, buffer): # 實現(xiàn)自定義 RAW 格式解析 raw_data = self._parse_custom_format(buffer) self.set_as_raw(bytes(raw_data)) return -1, 0 # 注冊解碼器 Image.register_decoder("MYRAW", RAWDecoder) Image.register_extensions("MYRAW", [".raw"])
2. 編寫濾鏡插件
from PIL import ImageFilter class KaleidoscopeFilter(ImageFilter.BuiltinFilter): name = "Kaleidoscope" filterargs = (5, 5), 16, 0, ( 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1 ) img.filter(KaleidoscopeFilter()).show()
二十一、工程化實踐
1. 圖像處理微服務(wù)架構(gòu)
# 使用 FastAPI 構(gòu)建 REST API from fastapi import FastAPI, File, UploadFile from PIL import Image import io app = FastAPI() @app.post("/enhance") async def enhance_image(file: UploadFile = File(...)): img = Image.open(io.BytesIO(await file.read())) # 執(zhí)行處理管線 enhanced = (img.convert('RGB') .filter(ImageFilter.SHARPEN) .enhance(contrast=1.2) .resize((1024, 768))) byte_arr = io.BytesIO() enhanced.save(byte_arr, format='JPEG') return Response(content=byte_arr.getvalue(), media_type="image/jpeg")
2. 自動化測試框架
import unittest from PIL import Image, ImageChops class ImageTests(unittest.TestCase): def test_watermark(self): original = Image.new('RGB', (800, 600), 'white') watermarked = add_watermark(original.copy(), "Test") # 驗證水印位置和內(nèi)容 diff = ImageChops.difference(original, watermarked) self.assertGreater(diff.getbbox()[2], 700) # 檢查右下角變化 def test_performance(self): large_img = Image.new('RGB', (10000, 10000)) start = time.time() large_img.thumbnail((1000, 1000)) self.assertLess(time.time() - start, 1.0)
二十二、前沿應(yīng)用案例
1. AI 藝術(shù)風(fēng)格遷移
# 結(jié)合 Pillow 與深度學(xué)習(xí)模型 def style_transfer(content_img, style_img): # 加載預(yù)訓(xùn)練模型(需安裝 torch 和 torchvision) from torchvision.models import vgg19 model = vgg19(pretrained=True).features.eval() # 特征提取與風(fēng)格遷移算法... # (此處實現(xiàn)具體遷移邏輯) return Image.fromarray(output) content = Image.open("photo.jpg") style = Image.open("starry_night.jpg") artwork = style_transfer(content, style)
2. 動態(tài)二維碼生成
from PIL import Image, ImageDraw import qrcode def animated_qr(data, logo_path): base = qrcode.make(data).convert('RGBA') logo = Image.open(logo_path).resize((100, 100)) frames = [] for angle in range(0, 360, 30): rotated_logo = logo.rotate(angle) frame = base.copy() frame.alpha_composite(rotated_logo, ((frame.width-100)//2, (frame.height-100)//2)) frames.append(frame) frames[0].save("qr_animation.gif", save_all=True, append_images=frames[1:], duration=200, loop=0, optimize=True)
二十三、調(diào)試與性能分析
1. 內(nèi)存分析工具
import tracemalloc from PIL import Image tracemalloc.start() # 測試代碼塊 with Image.open("large.tiff") as img: processed = img.resize((2000, 2000)) processed.save("output.jpg") snapshot = tracemalloc.take_snapshot() top_stats = snapshot.statistics('lineno') print("[ 內(nèi)存消耗 Top 10 ]") for stat in top_stats[:10]: print(stat)
2. 性能剖析
# 使用 cProfile 分析處理流程 python -m cProfile -s cumulative image_processor.py
二十四、跨平臺開發(fā)注意事項
- 字體處理兼容性
# 安全字體加載方案 def safe_font_loading(font_path, fallback_size=20): try: return ImageFont.truetype(font_path, size=fallback_size) except IOError: print(f"字體 {font_path} 加載失敗,使用系統(tǒng)默認字體") return ImageFont.load_default()
- 路徑處理規(guī)范
from pathlib import Path input_path = Path("input_images") / "special_chars_測試.jpg" output_path = input_path.with_name(f"processed_{input_path.name}")
二十五、資源與進階學(xué)習(xí)
官方文檔擴展閱讀
- 高級圖像變換:
Image.transform()
方法 - 分塊編碼器:
JpegEncoder
和WebPEncoder
- 圖像協(xié)議:支持
HTTP
、FTP
等協(xié)議直接讀取
- 高級圖像變換:
通過掌握這些高級技術(shù),將能夠:
- 處理專業(yè)領(lǐng)域的圖像分析需求
- 構(gòu)建企業(yè)級圖像處理系統(tǒng)
- 優(yōu)化處理流程達到工業(yè)級性能
- 開發(fā)自定義圖像處理擴展
- 集成 Pillow 到現(xiàn)代 AI 工作流
建議實踐方向:開發(fā)智能相冊管理系統(tǒng)、創(chuàng)建醫(yī)學(xué)影像分析工具、構(gòu)建云端圖像處理 API 服務(wù),或?qū)崿F(xiàn)實時視頻幀處理管道。持續(xù)關(guān)注 Pillow 的 GitHub 倉庫(https://github.com/python-pillow/Pillow)獲取最新功能更新。
以上就是Python Pillow庫詳細介紹與代碼示例的詳細內(nèi)容,更多關(guān)于Python Pillow庫介紹的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
關(guān)于Python文本生成的Beam?Search解碼問題
這篇文章主要介紹了Python文本生成的Beam?Search解碼,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07Kmeans均值聚類算法原理以及Python如何實現(xiàn)
這個算法中文名為k均值聚類算法,首先我們在二維的特殊條件下討論其實現(xiàn)的過程,方便大家理解。2020-09-09Python內(nèi)置函數(shù)all()的實現(xiàn)
Python內(nèi)置函數(shù)?all()?用于判斷可迭代對象中的所有元素是否都為真值(Truthy),是邏輯判斷的重要工具,下面就來具體介紹如何使用,感興趣的可以了解一下2025-04-04Python PyQt5實戰(zhàn)項目之網(wǎng)速監(jiān)控器的實現(xiàn)
PyQt5以一套Python模塊的形式來實現(xiàn)功能。它包含了超過620個類,600個方法和函數(shù)。它是一個多平臺的工具套件,它可以運行在所有的主流操作系統(tǒng)中,包含Unix,Windows和Mac OS。PyQt5采用雙重許可模式。開發(fā)者可以在GPL和社區(qū)授權(quán)之間選擇2021-11-11