图片隐写学习笔记(一)

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的个人理解,有所纰漏在所难免,欢迎批评指正!

 



posted on 2021-07-07 19:34  HOr7z  阅读(425)  评论(0编辑  收藏  举报