You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用PIL实现多像素块图像像素化?求空间高效代码方案

实现多像素块的高效像素化(Pillow)

嘿,我来帮你搞定多块像素化的问题!你已经成功实现了1x1的整体平均色像素化,现在咱们把这个逻辑扩展成网格状的像素块,同时保证空间效率——不用存储所有像素的RGB值,而是按需计算每个块的平均值。

先梳理下你现有代码的问题

你当前的代码逻辑有点小问题:

  • 只遍历了前40x40的像素,却把整个图像都设成最后一个cow的颜色,完全没用到计算出的平均色y/z/t
  • 存储所有像素RGB到列表的方式会占用大量内存,尤其是处理大图像时更明显

空间高效的多块像素化实现思路

核心思路是按网格遍历每个像素块,实时计算块内RGB平均值,直接填充块内像素,不用额外存储所有像素数据。具体步骤:

  1. 定义每个像素块的尺寸(比如10x10像素)
  2. 按网格遍历每个块的起始坐标
  3. 对每个块,累加内部所有像素的RGB值,计算平均值
  4. 将整个块的像素统一设置为这个平均色
  5. 处理图像边缘的不完整块(避免越界)

完整代码实现

from PIL import Image

def pixelate_image(image_path, target_size=(200, 200), block_size=(10, 10)):
    # 打开图像并缩放到目标尺寸
    actual = Image.open(image_path)
    og = actual.resize(target_size)
    pixel_data = og.load()
    img_width, img_height = og.size
    block_w, block_h = block_size

    # 遍历每个像素块的起始坐标(按块大小步进)
    for y_start in range(0, img_height, block_h):
        # 处理边缘:如果剩余高度不足块高,取到图像底部
        y_end = min(y_start + block_h, img_height)
        for x_start in range(0, img_width, block_w):
            # 处理边缘:如果剩余宽度不足块宽,取到图像右侧
            x_end = min(x_start + block_w, img_width)
            
            # 初始化当前块的RGB累加和与像素计数
            r_sum = g_sum = b_sum = 0
            pixel_count = 0

            # 遍历块内所有像素,累加RGB值
            for y in range(y_start, y_end):
                for x in range(x_start, x_end):
                    r, g, b = pixel_data[x, y]
                    r_sum += r
                    g_sum += g
                    b_sum += b
                    pixel_count += 1
            
            # 计算块内平均RGB(整数除法保证颜色值为0-255)
            r_avg = r_sum // pixel_count
            g_avg = g_sum // pixel_count
            b_avg = b_sum // pixel_count

            # 将整个块的像素设置为平均色
            for y in range(y_start, y_end):
                for x in range(x_start, x_end):
                    pixel_data[x, y] = (r_avg, g_avg, b_avg)
    
    return og

# 调用示例
pixelated_img = pixelate_image('My image', target_size=(200, 200), block_size=(10, 10))
pixelated_img.show()

关键优化点(空间高效)

  • 没有用列表存储所有像素的RGB值,而是每个块单独计算累加和,计算完成后直接填充,内存占用仅为单个块的临时变量大小
  • 自动处理图像边缘的不完整块,避免索引越界问题
  • 代码模块化,方便调整目标尺寸和块大小

更简洁的写法(利用PIL内置方法)

如果你想让代码更简洁,也可以用crop方法提取块,再计算块的平均色:

from PIL import Image

def pixelate_image_simple(image_path, target_size=(200, 200), block_size=(10, 10)):
    actual = Image.open(image_path)
    og = actual.resize(target_size)
    img_width, img_height = og.size
    block_w, block_h = block_size

    for y_start in range(0, img_height, block_h):
        y_end = min(y_start + block_h, img_height)
        for x_start in range(0, img_width, block_w):
            x_end = min(x_start + block_w, img_width)
            # 裁剪出当前块
            block = og.crop((x_start, y_start, x_end, y_end))
            # 计算块内平均RGB
            r_avg, g_avg, b_avg = tuple(sum(c) // len(c) for c in zip(*block.getdata()))
            # 创建纯色块并粘贴回原图
            solid_block = Image.new('RGB', (x_end - x_start, y_end - y_start), (r_avg, g_avg, b_avg))
            og.paste(solid_block, (x_start, y_start))
    
    return og

# 调用示例
pixelated_img = pixelate_image_simple('My image', target_size=(200, 200), block_size=(10, 10))
pixelated_img.show()

这种写法更简洁,可读性更强,内存效率也不错,因为crop和getdata都是按需处理的。

内容的提问来源于stack exchange,提问作者user13237630

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 18:13:14