Python图像像素位置打乱与还原异常:生成图像全黑问题排查
图像像素打乱加密/还原:全黑问题修复方案
问题根源
你的代码存在两处致命问题:
- 解密逻辑完全错误:直接用打乱索引去索引打乱后的像素数组,无法将像素映射回原始位置。
- 未处理图像格式与数据类型:PNG图像可能带Alpha通道,或数组类型被隐式转换,导致PIL无法正确渲染图像。
修复后的可运行代码
from PIL import Image import numpy as np # 加载并统一图像格式(RGB,如需保留透明度改用RGBA) img = Image.open('test.png').convert('RGB') # 转为uint8类型的NumPy数组,确保PIL兼容 img_array = np.array(img, dtype=np.uint8) # 获取图像尺寸参数 height, width, channels = img_array.shape total_pixels = height * width # 展平像素(按像素维度展平,保留每个像素的通道信息) flat_pixels = img_array.reshape(total_pixels, channels) # 生成原始索引与随机打乱索引 original_indices = np.arange(total_pixels) # 设置随机种子,保证加密解密的一致性 np.random.seed(42) shuffled_indices = np.random.permutation(original_indices) # --- 加密过程 --- shuffled_pixels = flat_pixels[shuffled_indices] shuffled_img_array = shuffled_pixels.reshape(height, width, channels) # 保存加密图像 Image.fromarray(shuffled_img_array).save('shuffled_image.png') # 保存打乱索引(解密必需) np.savetxt('shuffle_key.txt', shuffled_indices.astype(int), fmt='%d') # --- 解密过程 --- # 加载打乱索引 loaded_key = np.loadtxt('shuffle_key.txt', dtype=int) # 生成逆排列索引:找到每个原始位置对应的打乱后像素位置 reverse_key = np.argsort(loaded_key) # 还原像素位置 restored_pixels = shuffled_pixels[reverse_key] restored_img_array = restored_pixels.reshape(height, width, channels) # 保存还原图像 Image.fromarray(restored_img_array).save('restored_image.png')
关键修复细节
- 逆索引生成:用
np.argsort(shuffled_indices)生成解密所需的逆排列。因为shuffled_indices记录了「原始索引→新位置」的映射,argsort能反向得到「原始位置→对应打乱后像素的位置」,这是正确还原的核心。 - 图像格式统一:通过
convert('RGB')消除Alpha通道的干扰,避免因数组形状不一致导致的展平/重塑错误。 - 数据类型固化:指定
dtype=np.uint8确保数组类型符合PIL对图像数据的要求,防止因类型转换导致像素值异常(比如全黑)。 - 随机种子固定:添加
np.random.seed(42)保证每次运行的打乱顺序一致,否则加密和解密使用不同的随机序列,无法还原图像。
灰度图适配说明
如果处理的是灰度图像,只需将convert('RGB')改为convert('L'),并调整数组处理逻辑:
# 灰度图处理示例 img = Image.open('test_gray.png').convert('L') img_array = np.array(img, dtype=np.uint8) height, width = img_array.shape total_pixels = height * width flat_pixels = img_array.flatten() # 后续加密解密逻辑与RGB一致,仅重塑时改为(height, width)
内容的提问来源于stack exchange,提问作者Dr. Kalyan N
相关产品推荐
相关产品推荐

