最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python PIL庫實現(xiàn)九宮格圖片的裁剪與拼接方法

 更新時間:2026年05月28日 15:31:49   作者:detayun  
本文以抖音九宮格驗證碼為例,為大家詳細(xì)詳細(xì)介紹了如何通過Python的PIL庫實現(xiàn)圖片裁剪與拼接,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下

在驗證碼識別、圖片預(yù)處理等場景中,經(jīng)常需要從一張大圖中按固定坐標(biāo)裁出多張小圖,再重新拼成一張新圖。本文以抖音九宮格驗證碼為例,完整演示裁剪與拼接的實現(xiàn)。

一、需求拆解

原始圖是一張九宮格大圖,每張小圖之間有間隙。目標(biāo):

  1. 按坐標(biāo)裁出 9 張小圖
  2. 每張縮放到 110×110
  3. 拼成一張 330×330 的新圖

二、核心代碼

from PIL import Image

img = Image.open(r"微信圖片_20260528094122_13_1856.png")

# 九宮格坐標(biāo):3行 × 3列
rect_list = [
    [(1,0,166,165),  (181,0,346,165),  (361,0,525,165)],     # 第一行
    [(1,180,166,345),(181,180,346,345),(361,180,525,345)],   # 第二行
    [(1,360,166,525),(181,360,346,525),(361,360,525,525)],   # 第三行
]

# 創(chuàng)建 330×330 空白圖(白色背景)
new_img = Image.new("RGB", (330, 330), (255, 255, 255))

for y in range(3):
    for x in range(3):
        # 1. 裁剪
        s_img = img.crop(rect_list[y][x])
        # 2. 高質(zhì)量縮放(關(guān)鍵:加 LANCZOS)
        s_img = s_img.resize((110, 110), resample=Image.LANCZOS)
        # 3. 粘貼到新圖(每張 110px,按網(wǎng)格排列)
        new_img.paste(s_img, (x * 110, y * 110))

new_img.save("result.png")

三、關(guān)鍵細(xì)節(jié)

1. crop() 裁剪

crop() 接收一個四元組 (left, top, right, bottom)

s_img = img.crop((1, 0, 166, 165))  # 左上(1,0) 到 右下(166,165)

坐標(biāo)從大圖的 rect_list 中逐行讀取。

2. resize() 高質(zhì)量縮放

必須指定 resample=Image.LANCZOS,否則默認(rèn)用 BILINEAR,縮放后模糊。

濾波器質(zhì)量速度
NEAREST?最快
BILINEAR??
BICUBIC???中等
LANCZOS?????較慢

PIL 10.0+ 寫法:

s_img.resize((110, 110), resample=Image.Resampling.LANCZOS)

3. paste() 拼接

新圖 330×330,每張小圖 110×110,共 3×3 排列。粘貼坐標(biāo)按網(wǎng)格計算:

paste_x = x * 110
paste_y = y * 110
小圖xy粘貼位置
(0,0)00(0, 0)
(0,1)10(110, 0)
(1,0)01(0, 110)
(2,2)22(220, 220)

四、常見坑

問題原因解決
s_img.size() 報錯size 是屬性不是方法去掉括號:s_img.size
拼接后有白邊小圖尺寸不一致確保 resize 統(tǒng)一為 110×110
縮放后模糊沒加 LANCZOSresize(..., resample=Image.LANCZOS)
保存后質(zhì)量差JPEG 默認(rèn) quality=75save(..., quality=95)

五、透明背景版本

如果需要透明底:

new_img = Image.new("RGBA", (330, 330), (0, 0, 0, 0))  # 透明背景
new_img.save("result.png")  # 必須存 PNG

總結(jié):crop 裁 → LANCZOS 縮 → paste 拼,三步搞定九宮格重排。

六、知識擴(kuò)展

使用 Python 的 Pillow(PIL 的 fork 庫)進(jìn)行圖片裁剪與拼接非常方便。下面分別介紹裁剪和拼接的方法,并給出完整示例。

安裝 Pillow

pip install Pillow

圖片裁剪(crop)

Image.crop(box) 方法用于裁剪圖像,box 是一個四元組 (left, upper, right, lower),坐標(biāo)基于原圖左上角為原點。

from PIL import Image

# 打開圖片
img = Image.open('input.jpg')

# 定義裁剪區(qū)域 (左, 上, 右, 下)
box = (100, 100, 400, 400)  # 從(100,100)到(400,400)的正方形
cropped_img = img.crop(box)

# 保存裁剪結(jié)果
cropped_img.save('cropped.jpg')

動態(tài)裁剪示例:裁剪圖片的中心區(qū)域

width, height = img.size
crop_size = 300
left = (width - crop_size) // 2
top = (height - crop_size) // 2
right = left + crop_size
bottom = top + crop_size
center_crop = img.crop((left, top, right, bottom))
center_crop.save('center_crop.jpg')

圖片拼接(拼接)

拼接需要先創(chuàng)建一張足夠大的空白畫布,然后將各張圖片粘貼上去。

1. 水平拼接(兩張圖并排)

# 打開兩張圖片
img1 = Image.open('pic1.jpg')
img2 = Image.open('pic2.jpg')

# 確保它們高度一致(可選)
if img1.height != img2.height:
    # 將高者按比例縮放到與低者一致
    new_height = min(img1.height, img2.height)
    img1 = img1.resize((int(img1.width * new_height / img1.height), new_height))
    img2 = img2.resize((int(img2.width * new_height / img2.height), new_height))

# 創(chuàng)建新畫布,寬度為兩張圖寬度之和,高度取較大者
total_width = img1.width + img2.width
max_height = max(img1.height, img2.height)
new_img = Image.new('RGB', (total_width, max_height))

# 粘貼圖片
new_img.paste(img1, (0, 0))
new_img.paste(img2, (img1.width, 0))

new_img.save('horizontal_merge.jpg')

2. 垂直拼接(兩張圖上下堆疊)

img1 = Image.open('pic1.jpg')
img2 = Image.open('pic2.jpg')

total_height = img1.height + img2.height
max_width = max(img1.width, img2.width)
new_img = Image.new('RGB', (max_width, total_height))

new_img.paste(img1, (0, 0))
new_img.paste(img2, (0, img1.height))

new_img.save('vertical_merge.jpg')

3. 多圖網(wǎng)格拼接(例如 2x2)

images = [Image.open(f'pic{i}.jpg') for i in range(1, 5)]  # 4張圖
rows, cols = 2, 2

# 計算每個小圖的尺寸(這里假設(shè)所有圖片尺寸相同)
width, height = images[0].size

# 創(chuàng)建大圖
grid_img = Image.new('RGB', (cols * width, rows * height))

for i, img in enumerate(images):
    row = i // cols
    col = i % cols
    grid_img.paste(img, (col * width, row * height))

grid_img.save('grid_merge.jpg')

4. 靈活拼接(列表 + 自動適應(yīng))

封裝一個函數(shù),支持任意數(shù)量的圖片水平或垂直拼接:

def merge_images(image_paths, direction='horizontal'):
    images = [Image.open(path) for path in image_paths]
    
    if direction == 'horizontal':
        total_width = sum(img.width for img in images)
        max_height = max(img.height for img in images)
        new_img = Image.new('RGB', (total_width, max_height))
        x_offset = 0
        for img in images:
            new_img.paste(img, (x_offset, 0))
            x_offset += img.width
    elif direction == 'vertical':
        total_height = sum(img.height for img in images)
        max_width = max(img.width for img in images)
        new_img = Image.new('RGB', (max_width, total_height))
        y_offset = 0
        for img in images:
            new_img.paste(img, (0, y_offset))
            y_offset += img.height
    else:
        raise ValueError("direction must be 'horizontal' or 'vertical'")
    
    return new_img

# 使用
result = merge_images(['a.jpg', 'b.jpg', 'c.jpg'], 'horizontal')
result.save('merged.jpg')

高級技巧:在拼接時添加邊框或間距

可以在兩張圖片之間留白:

spacing = 10
total_width = img1.width + spacing + img2.width
new_img = Image.new('RGB', (total_width, max_height))
new_img.paste(img1, (0, 0))
new_img.paste(img2, (img1.width + spacing, 0))

或者添加白色背景:

bg = Image.new('RGB', (total_width, max_height), color='white')
bg.paste(img1, (0, 0))
bg.paste(img2, (img1.width + spacing, 0))

注意事項

圖片模式Image.open() 可能返回不同的模式(如 RGBA、RGB、L),拼接時建議統(tǒng)一轉(zhuǎn)換為 RGB:

img = img.convert('RGB')

性能:大量高清圖片拼接時內(nèi)存占用較大,可以考慮逐張?zhí)幚砘蚴褂酶讓拥?nbsp;numpy 加速。

透明背景:如果原圖有透明通道(PNG),創(chuàng)建新畫布時應(yīng)使用 'RGBA' 模式。

完整示例:一鍵批量裁剪并拼接

假設(shè)有一個文件夾里的圖片需要先裁剪中心區(qū)域,然后按 2x3 網(wǎng)格拼接:

import os
from PIL import Image
def batch_crop_and_merge(folder, crop_size, rows, cols, output_path):
    # 獲取所有圖片
    paths = [os.path.join(folder, f) for f in os.listdir(folder) if f.endswith(('.jpg', '.png'))]
    images = []
    for path in paths:
        img = Image.open(path)
        # 中心裁剪
        w, h = img.size
        left = (w - crop_size) // 2
        top = (h - crop_size) // 2
        cropped = img.crop((left, top, left + crop_size, top + crop_size))
        images.append(cropped)
    # 網(wǎng)格拼接
    grid_img = Image.new('RGB', (cols * crop_size, rows * crop_size))
    for idx, img in enumerate(images):
        if idx >= rows * cols: break
        x = (idx % cols) * crop_size
        y = (idx // cols) * crop_size
        grid_img.paste(img, (x, y))
    grid_img.save(output_path)
    print(f"已保存到 {output_path}")
# 調(diào)用
batch_crop_and_merge('./photos', crop_size=300, rows=2, cols=3, output_path='grid_result.jpg')

到此這篇關(guān)于Python PIL庫實現(xiàn)九宮格圖片的裁剪與拼接方法的文章就介紹到這了,更多相關(guān)Python圖片裁剪與拼接內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

铜川市| 资溪县| 保德县| 儋州市| 饶平县| 大城县| 通道| 积石山| 句容市| 弋阳县| 惠东县| 商洛市| 昭通市| 金华市| 乳源| 镇沅| 吉林市| 松桃| 富源县| 江阴市| 祥云县| 甘谷县| 三台县| 商南县| 邵阳市| 托克逊县| 柯坪县| 康平县| 越西县| 兰州市| 青冈县| 天峻县| 灌阳县| 阜新| 英山县| 万安县| 吴江市| 宜阳县| 福鼎市| 西乌| 子长县|