轻微改变图片中像素的RGB值,肉眼无法 察觉
将8bit R/G/B中的最低1bit,用于隐藏一 个数据文件(如文本)
每3个像素可以隐藏1个字节
注意使用不失真图像格式
BMP/PNG格式
要求:
1)提供图片和数据文件,生成隐藏信息的图片
2)从隐藏信息的图片中提取数据文件
做这个必须弄清楚原理,不然无从下手:
- 图片都由像素组成,一个字节=8位
- 一个像素包含红绿蓝(RGB)三个颜色通道的值,最小值为0,用二进制表示为0b00000000,0b是前缀,代表后面的数字是二进制。最大值为255,用二进制表示为0b11111111,0b后面的8位数字,即一个字节,就代表了颜色的值。一个像素有3个字节。
- 获取一个像素的数据,我们就可以得出(R,G,B)的值,如(67, 140, 255),我们把数字转化为二进制(0b1000011, 0b10001100, 0b11111111)。
- 对人的肉眼来说,颜色值差1,是看不出区别的。如颜色值255,和254,254的二进制为0b11111110。我们就可以利用最后一位数字来隐藏信息。这样,一个像素就能存3位(取RGB各最后一位),那么我要存一个字节的信息,需要8位,可知起码需要3个像素才能保存一个字节的信息
- 我把想隐藏的信息化成二进制,假设0b10101010,把0b后面的每一位数字都依次替换到每一个像素的RGB最后一位里,则达到了隐藏信息的目的。要提取时,直接取像素的RGB值里的最后一个数字,再重新组合成信息,就达到了解密的效果。
My answer
思路:对零基础的来说太难了,上网找资料,整了两天。。搞了个最基本的,只能存英文和数字,加密信息不能超过255长度,因为我只用8位来保存信息,取信息时也是8位8位的取。如我要写入’i love you’, 这个共有10个字符。那么我的前8位纪录的就是二进制的10。
写入数据不知道有没有更好的方法。。希望有高手指点一二
from PIL import Image
# 将数据写入图片的步骤
image = Image.open('bk.bmp')
strings = 'i love you'
'''
信息加密
'''
def encodeimg(image,strings):
# 先计算要写入的数据会占用多少个像素,RGB,3个像素装一个字节
n = (len(strings) + 1) * 3 # 需要n个像素,第一个纪录共有多少数据量
rgblst = list(image.getdata())[:n] # 得到图片的RGB,只取所需要的像素
# 进行位移计算,把二进制最后一位都变0
rlst = [(r >> 1 <<