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

Python PIL图像正方形像素块交换问题:一张输出未正常修改

问题分析与修复

核心错误原因

你的代码中pixel_maps_for_swap直接引用了pixel_maps_for_output_images的两个像素映射对象,并非独立的临时存储副本。这导致交换逻辑执行时,第二张图(NEG)的像素会被错误地覆盖回原始值:

  1. 执行pixel_maps_for_swap[0][pos] = pixel_maps_for_output_images[0][pos]时,本质是把像素值赋给自身,无实际意义;
  2. 修改第一张图的像素为第二张图的原始值后,第二张图的像素被赋值为swap0[pos]——而swap0就是第一张图的像素映射,此时第一张图的像素已经被修改,所以第二张图的像素最终被设为修改后的值(和自身原始值一致),导致NEG图完全没有变化。

修复后的代码

from PIL import Image
from inspect import currentframe, getframeinfo

def pprint(line_number, message):
    print(f'L_{line_number}: {message}')

# 路径与参数配置
images_path = r'C:\_D_Drive\_pictures\for_asking'
check_size = 100
width = 400
height = 400
output_images_names = [
    images_path + r"\___OUTPUT_IM_" + str(check_size) + r"_POS.png",
    images_path + r"\___OUTPUT_IM_" + str(check_size) + r'_NEG.png'
]

# 初始化原始图像
red_img = Image.new(mode="RGB", size=(width, height), color="red")
green_img = Image.new(mode="RGB", size=(width, height), color="green")
output_images = [red_img, green_img]
pixel_maps = [output_images[0].load(), output_images[1].load()]

pprint(getframeinfo(currentframe()).lineno, "开始生成棋盘格交换效果...")

def swap_square(run_number, odd_or_even, i_start, j_start):
    global pixel_maps, check_size, width, height
    sq_pos_neg_string = ["POS", "NEG"]

    # 仅在需要调试时启用临时图生成
    make_temp_squares = False
    if make_temp_squares:
        temp_img = Image.new(mode="RGB", size=(width, height), color="lightgray")
        temp_map = temp_img.load()
        # 先复制第一张图的像素
        for u in range(width):
            for v in range(height):
                temp_map[u, v] = pixel_maps[0][u, v]
        # 标记当前要交换的区域
        for u in range(check_size):
            for v in range(check_size):
                x = u + i_start
                y = v + j_start
                if x < width and y < height:
                    temp_map[x, y] = (255, 0, 255)
        temp_img.save(
            f"{images_path}\\_temp_square_{run_number}_{check_size}_{sq_pos_neg_string[odd_or_even]}_{i_start}_{j_start}.png",
            format="png"
        )

    # 核心交换逻辑:用临时变量存储像素值,避免引用导致的覆盖问题
    for k in range(check_size):
        for l in range(check_size):
            x = k + i_start
            y = l + j_start
            if x < width and y < height:
                if odd_or_even == 1:
                    # 先保存两个位置的原始像素值
                    pos_pixel = pixel_maps[0][x, y]
                    neg_pixel = pixel_maps[1][x, y]
                    # 执行交换
                    pixel_maps[0][x, y] = neg_pixel
                    pixel_maps[1][x, y] = pos_pixel

    pprint(getframeinfo(currentframe()).lineno, f"odd_or_even: {odd_or_even} 区域坐标:{i_start}:{j_start}")
    # 调试用中间保存(可选)
    # output_images[0].save(f"{images_path}\\__run#{run_number}_{sq_pos_neg_string[odd_or_even]}_oe_0.png", format="png")
    # output_images[1].save(f"{images_path}\\__run#{run_number}_{sq_pos_neg_string[odd_or_even]}_oe_1.png", format="png")

run_number = 0
for j in range(0, height, check_size):
    if height - j < check_size:
        pprint(getframeinfo(currentframe()).lineno, "注意:存在垂直边缘区域,尺寸不足方块大小")
    for i in range(0, width, check_size):
        if width - i < check_size:
            pprint(getframeinfo(currentframe()).lineno, "注意:存在水平边缘区域,尺寸不足方块大小")
        # 简化棋盘格奇偶判断逻辑
        odd_even = ((i // check_size) + (j // check_size)) % 2
        run_number += 1
        swap_square(run_number, odd_even, i, j)

# 保存最终结果
output_images[0].save(output_images_names[0], format="png")
output_images[1].save(output_images_names[1], format="png")

额外优化点

  1. 移除了冗余的adjustable_woven_images代码(这部分创建后未被实际使用);
  2. 简化了棋盘格奇偶性的计算逻辑,去掉不必要的取模操作;
  3. 优化了变量命名,提升代码可读性;
  4. 注释了非必要的中间图像保存代码,可根据调试需求启用。

内容的提问来源于stack exchange,提问作者Jean-Paul Bardou

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 07:13:10