美文网首页
图片加数字水印

图片加数字水印

作者: 路人乙yh | 来源:发表于2018-10-09 19:44 被阅读38次

    数字水印介绍

    常见的图片水印多是在图片上附上文字、logo等信息,可以直观地看出来,除了这种水印外,好可以给图片加一种看不见的水印,比如说是文字信息。

    实现原理

    • 图像中的每个像素通常用RGB三个0~255的值来表示,转化为二进制就是00000000~11111111。

    • 把每个值的最后一位全部设为零,这种变化人眼观察不到。

    • 这样空出来的最后一位就可以用来存储信息。

    • 提取信息的过程就是上述过程的逆:把像素值提取出来,选择最后一位,拼出信息。

    代码实现

    导入用到的包

    from PIL import Image
    import numpy as np
    import functools
    

    加密过程

    def embedding_info(picname, savename, text):
        text += '#%#'    #在文本末端加入一个标记符,提取过程中以此为结束标记
        # 读取图片
        im = np.array(Image.open(picname))
        rows, columns, colors = im.shape
        embed = []
        for c in text:
            bin_sign = (bin(ord(c))[2:]).zfill(16)    #(bin(ord(c))[2:])是转化为2进制, .zfiil(16)是原来字符右对齐,左边全部用0填充
            for i in range(16):
                embed.append(int(bin_sign[i]))
                
        count = 0
        for row in range(rows):
            for col in range(columns):
                for color in range(colors):
                    if count < len(embed):
                        im[row][col][color] = im[row][col][color] // 2 * 2 +embed[count]   #用地板除乘以2,使得末尾数字为0,再把文本字符转化为2进制的数字填充进去
                        count += 1
        Image.fromarray(im).save(savename)
    

    解密过程

    def extract_info(picname):
        im = np.array(Image.open(picname))
        rows, columns, colors = im.shape
        text = ""
        extract = np.array([], dtype = int)
        
        count = 0
        for row in range(rows):
            for col in range(columns):
                for color in range(colors):
                    extract = np.append(extract, im[row][col][color] % 2)  #注1
                    count += 1
                    if count % 16 ==0:
                        bcode = functools.reduce(lambda x, y: str(x) + str(y), extract)  #注2
                        cur_char = chr(int(bcode, 2))    #将2进制转化为字符
                        text += cur_char
                        if cur_char == '#' and text[:-3] == '#%#':
                            return text[-3:]     #如果return语句被执行,就会退出当前函数体,结束提取过程
                        extract = np.array([], dtype = int)
    

    注1:np.append 是将传入的两个元素横着合并到一起,如np.append([1,2,3] , [9,8,7])的输出是[1,2,3,4,9,8,7]
    注2:functools.reduce(lambda x: x*2, [1,2,3,4])的输出为(((1*2)*2)*2)*2

    运行代码

    def main():
        text = "Hello, world!"
        embedding_info('C:\\Users\\yyy\\Documents\\img_111.png', 'After.png', text)
        extract_info('After.png')
        
    if __name__ == '__main__':
        main()
    

    实现效果

    原图 Before.png
    处理后 After.png

    相关文章

      网友评论

          本文标题:图片加数字水印

          本文链接:https://www.haomeiwen.com/subject/icasaftx.html