You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python中基于PIL实现LSB隐写后如何从二进制数据重建图像

我帮你分析下问题所在,以及怎么修复这个隐写术的图像重建问题:

你的核心问题出在处理后的二进制字符串没有转换回整数,也没有恢复成图像需要的像素结构Image.fromarray()需要的是数值数组(比如0-255的uint8整数),而不是你保存的二进制字符串数组,这就是为什么生成的图像无效。

接下来一步步给你修正:

1. 核心问题拆解

  • 你把每个RGB值转成了'0bxxxxxxx'格式的二进制字符串,修改LSB后没有转回十进制整数
  • 展平的RGB值列表没有重新组织成原始图像的像素元组结构(比如每个像素对应3个RGB值)
  • 缺少将处理后的数据正确映射回图像格式的步骤

2. 修正后的完整代码

from PIL import Image
import json

def bincon(image_path):
    im = Image.open(image_path, 'r')
    pix_val = list(im.getdata())  # 获取每个像素的RGB元组
    pix_val_flat = [x for sets in pix_val for x in sets]  # 展平为单个RGB值的列表
    # 直接遍历元素生成二进制字符串,简化代码
    pixel_binaries = [bin(val) for val in pix_val_flat]
    # 返回图像尺寸和模式,方便后续重建时保持一致
    return pixel_binaries, im.size, im.mode

# 待嵌入的秘密信息二进制串
injection = '0111001101100101011000110111001001100101011101000010000001101101011001010111001101110011011000010110011101100101001000000110100101101110011010100110010101100011011101000110100101101111011011100010000001101101011011110110110101100101011011100111010000100000011010000110010101101000011001010110100001100101011010000110010101101000011001010110100001100101'
injection_array = list(injection)  # 直接转为字符列表,简化循环

# 1. 获取原始图像的二进制数据、尺寸和模式
pixel_bin, img_size, img_mode = bincon("input_image.png")  # 替换为你的输入图像路径
modified_pixels = []
injectioncount = 0

# 2. 修改每个RGB值的LSB
for bin_str in pixel_bin:
    if injectioncount < len(injection_array):
        # 剥离最低位并替换为秘密信息的位
        new_bin_str = bin_str[:-1] + injection_array[injectioncount]
        injectioncount += 1
    else:
        # 秘密信息位用完后,保留原像素的最低位
        new_bin_str = bin_str
    # 将二进制字符串转回十进制整数(关键步骤)
    modified_val = int(new_bin_str, 2)
    modified_pixels.append(modified_val)

# 保存对比用的二进制数据(可选)
with open("comparison.json","w") as f:
    json.dump([bin(val) for val in modified_pixels], f, indent=2)

# 3. 重建图像:将展平的RGB值重新分组为像素元组
# 例如RGB模式下,每3个连续值组成一个像素的RGB元组
pixel_tuples = [tuple(modified_pixels[i:i+3]) for i in range(0, len(modified_pixels), 3)]

# 4. 创建并保存处理后的图像
im_out = Image.new(img_mode, img_size)
im_out.putdata(pixel_tuples)
im_out.save("output_image.png")
print("处理后的图像已保存为output_image.png")

关键修改说明

  • 增强bincon函数:返回图像的尺寸和模式,确保重建的图像和原始图像格式一致
  • 二进制转整数:用int(new_bin_str, 2)将修改后的二进制字符串转回0-255的有效RGB值
  • 恢复像素结构:把展平的RGB值重新分组为像素元组,再用putdata()方法写入新图像,比fromarray更直观可靠
  • 处理剩余像素:秘密信息位用完后,保留原始像素的LSB,避免破坏图像的其余部分

这样修改后,生成的output_image.png应该可以正常打开,肉眼几乎看不出变化,同时秘密信息已经嵌入到像素的最低有效位中了。

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

火山引擎 最新活动