Python中图片的切块与合并

5 篇文章 0 订阅

Python中图片的切块与合并

有时候我们处理的图片过大而内存不足时,切块是一种不错的方法,化整为零,分治处理。切块图片其实没必要存储,不过代码中还是进行了保存。
import os
from PIL import Image


def image_cut_and_merge(image_path, size=(256, 256), output_dir=''):
    scale = 4  # 放大的倍数
    # 获取图片的宽度和高度  
    img = Image.open(image_path)  # 默认RGB格式
    width, height = img.size  
    # 计算在宽度和高度上分别需要分割成多少块  
    tiles_x = (width + size[0] - 1) // size[0]  
    tiles_y = (height + size[1] - 1) // size[1]  
    assert (tiles_x =< 1) and (tiles_y =< 1), "原图片不能小于切块尺寸。"
    # 创建放大后图片粘贴空间
    target_size = scale * width, scale * height
    output_img = Image.new('RGB', target_size)

    # output_dir="out_puts" # 文件保存目录
    filename_without_extension = os.path.splitext(os.path.basename(image_path))[0]
        
    # 遍历所有块放大4倍
    # 重新优化了切块方法,避免无法整除而产生黑色区域
    borders={'x':[], 'y':[]} # 用于拼接图片
    for i in range(tiles_x):   
        for j in range(tiles_y):  
            # 计算当前块的左上角坐标  
            box = (i * size[0], j * size[1], (i + 1) * size[0], (j + 1) * size[1])  

            # 如果tile小于块尺寸,将会改变起始点
            width_diff = width - (i + 1) * size[0]
            height_diff = height - (j + 1) * size[1]
            if width_diff < 0:
                box = (i * size[0] + width_diff, j * size[1], width, (j + 1) * size[1])
            if height_diff < 0:
                box = (i * size[0], j * size[1] + height_diff, (i + 1) * size[0], height)
            if width_diff < 0 and height_diff < 0:
                box = (i * size[0] + width_diff, j * size[1] + height_diff, width, height)

            x = box[0] * scale # 图片拼接X坐标
            y = box[1] * scale  # 图片拼接Y坐标
            borders['x'].append(x)
            borders['y'].append(y)
            
            # 裁剪图片块  
            tile = img.crop(box)        

            ################## TODO 在这里对切的图进行想要的处理。例如放大4倍 ################
            tile = tile.resize((scale * size[0], scale * size[1]))

            # 保存切分图
            output_path = f"{filename_without_extension}_{i}_{j}.png" 
            if len(output_dir.strip()) > 0:
                output_path = f"{output_dir}/{filename_without_extension}_{i}_{j}.png" 
            tile.save(output_path)

            # 将放大后的图片拼接起来  
            output_img.paste(tile, (x, y))

    # 保存放大图
    output_path = f"{filename_without_extension}_x4.png"
    if len(output_dir.strip()) > 0:
        output_path = f"{output_dir}/{filename_without_extension}_x4.png" 
    output_img.save(output_path)

# 示例
image_cut_and_merge("qianzhi_croped.png", output_dir="out_puts")
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值