Python PIL图像正方形像素块交换问题:一张输出未正常修改
问题分析与修复
核心错误原因
你的代码中pixel_maps_for_swap直接引用了pixel_maps_for_output_images的两个像素映射对象,并非独立的临时存储副本。这导致交换逻辑执行时,第二张图(NEG)的像素会被错误地覆盖回原始值:
- 执行
pixel_maps_for_swap[0][pos] = pixel_maps_for_output_images[0][pos]时,本质是把像素值赋给自身,无实际意义; - 修改第一张图的像素为第二张图的原始值后,第二张图的像素被赋值为
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")
额外优化点
- 移除了冗余的
adjustable_woven_images代码(这部分创建后未被实际使用); - 简化了棋盘格奇偶性的计算逻辑,去掉不必要的取模操作;
- 优化了变量命名,提升代码可读性;
- 注释了非必要的中间图像保存代码,可根据调试需求启用。
内容的提问来源于stack exchange,提问作者Jean-Paul Bardou
相关产品推荐
相关产品推荐

