图片隐写学习笔记(一)
LSB (least significant bit)
在对图片进行处理之前,应当对目前常用的图像模式有所了解,大致为以下几类:
RGB 模式:Red,Green,Blue
RGBA模式:在RGB模式的基础上增加Alpha通道
CMYK模式:Cyan -青色,Magenta-洋红色,Yellow-黄色,blacK-黑色
HSB 模式:Hue-色相,Saturation-饱和度,Brightness-明亮度
灰度模式:L,I,F
而LSB隐写在大多数情况下会使用RGB或RGBA模式(之后将以RGB模式为例)。在这种模式下使用0~255的数值来对应表示三原色。
比如:
十进制下的(255,0,0)就表示红色,此时,如果将R通道的对应数值进行修改
十进制下:255——>254
二进制下:11111111——>11111110
将二进制中的最低位由1变为0,就会使R通道数值由255变为254,但这种变化是无法用人眼辨别的,于是就可以通过这样的方式来实现图片隐写
代码如下:
# 导入模块 from PIL import Image img_path = "img_path" img = Image.open(img_path, 'r') img = img.convert("RGB") pixel_value = list(img.getdata()) # print(pixel_value)输出每个像素的RGB值 R_value = [i[0] for i in pixel_value] #R通道的值 G_value = [i[1] for i in pixel_value] #G通道的值 B_value = [i[2] for i in pixel_value] #B通道的值 def low_to_zero(NEW_VALUE): temp = [] for i in range(len(NEW_VALUE)): temp.append('{:08b}'.format(NEW_VALUE[i])) new = [] for j in range(len(temp)): temp[j] = str(temp[j])[:-1] + '0' new.append(int(temp[j], 2)) return new # 将字符串转化为二进制数组 def turn_to_bin(INFO): INFO = list(INFO) turn_bin = [] for i in range(len(INFO)): temp = ord(INFO[i]) turn_bin.append('{:08b}'.format(temp)) # 类型为str,(turn_bin) return turn_bin # 将二进制数组打散 def turn_scatter(LIST): new_bin = [] for i in range(len(LIST)): for j in range(0, 8): new_bin.append(LIST[i][j]) return new_bin # 将new_bin 得到的数组加到像素中去 def change_img(LIST_IMG, LIST_BIN): changed = [] for i in range(len(LIST_BIN)): changed.append(int(LIST_BIN[i]) + int(LIST_IMG[i])) new_changed = changed + LIST_IMG[len(changed):] return new_changed information = "i am just a newbie" # print(turn_to_bin(information)) # print(turn_scatter(turn_to_bin(information))) new = low_to_zero(G_value) #print(new) # print(G_value) # print(low_to_zero(G_value)) # 改变change_img的第一个参数即可改变对应通道 new_changed = change_img(new, turn_scatter(turn_to_bin(information))) # print(new_changed) pim = img.load() width = img.size[0] height = img.size[1] count = 0 for w in range(0, width): for h in range(0, height): img.putpixel((h, w), (R_value[count], new_changed[count], B_value[count])) # pim[h, w] = (R_value[count], new_changed[count], B_value[count]) # 上一行这种方法也可以用 count = count + 1 img.save('XXX.png') # 图片只能存为无损格式,如 png,bitmap, tif #查看信息部分代码 from PIL import Image img_path = "XXX.png" img = Image.open(img_path, 'r') img = img.convert("RGB") pixel_value = list(img.getdata()) R_value = [i[0] for i in pixel_value] G_value = [i[1] for i in pixel_value] B_value = [i[2] for i in pixel_value] # print(R_value) def turn_to_bin(VALUE): values = [] for i in range(len(VALUE)): temp = str('{:08b}'.format(VALUE[i])) temp = temp[-1] values.append(int(temp)) return values def combine_bin(VALUES): new_values = [] for i in range(0, len(VALUES), 8): if i + 8 <= len(VALUES): VALUES[i] = str(VALUES[i]) + str(VALUES[i+1]) + str(VALUES[i+2]) + str(VALUES[i+3]) + str(VALUES[i+4]) + str(VALUES[i+5]) + str(VALUES[i+6]) + str(VALUES[i+7]) #这部分可以用循环改写…… new_values.append(VALUES[i]) else: pass return new_values def bin_to_int(NEW): dec = [] for i in range(len(NEW)): dec.append(int(NEW[i], 2)) asc = [] for j in range(len(dec)): asc.append(chr(dec[j])) return asc # print(turn_to_bin(G_value)) # print(combine_bin(turn_to_bin(G_value))) print(bin_to_int(combine_bin(turn_to_bin(G_value))))
结果显示:
最后的字符串可以再过滤出有效信息,然后进行合并。
以上代码实现均基于我对LSB的个人理解,有所纰漏在所难免,欢迎批评指正!