【python PIL】数字水印添加以及检测

2019-04-15 15:10发布

原理

图像像素颜 {MOD}数据高位保留,低位存储图像数据。 我知道算法很简单啦没有鲁棒性啦…… 不听口亨。

添加

#coding:utf-8 # author @Birdy from PIL import Image def addWaterMarking (pic , mark): # 预处理 img = Image.open(pic).convert("RGB") width, height = img.size # 读取大小 img_mark = Image.open(mark).convert("RGB") img_mark = img_mark.resize((width, height)) #缩放水印到文件大小 # 这几步也可以扔到后面做 img = img.point(lambda i: (int(i>>2))<<2) img_mark = img_mark.point(lambda i: round(i/85)) # 合成 img_pixels = list(img.getdata()) mark_pixels = list(img_mark.getdata()) # print img_pixels[:10] newpixels = [0 for i in range(len(img_pixels))] #先固定列表大小减少动态内存分配 for index in range(len(img_pixels)): #取出来的格式是truple 要先 list_temp = []; for i in range(3): list_temp.append(img_pixels[index][i] + mark_pixels[index][i]) newpixels[index] = tuple(list_temp) # print newpixels[:10] imn = Image.new("RGB", (width, height)) imn.putdata(data = newpixels) # imn.show() # 把加水印后的图像用png格式保存 这里不能用压缩格式吖 imn.save('static/output.png') return if __name__ == '__main__': addWaterMarking('back2.jpg','mark.jpg')

检测

检测的时候会需要检测图像和水印图,返回检测图像是否带有水印。 #coding:utf-8 # author @Birdy from PIL import Image,ImageChops def equal (im1, im2): return ImageChops.difference(im1, im2).getbbox() is None def testWaterMarking (pic , mark): # 预处理 img = Image.open(pic).convert("RGB") width, height = img.size # 读取大小 img_mark = Image.open(mark).convert("RGB") img_mark = img_mark.resize((width, height)) #缩放水印到文件大小 img_pixels = list(img.getdata()) # print img_pixels[:10] # 提取出来的水印 img_get = img.point(lambda i: (int(i&3))*85) # img_get.show() # 正常应该得到的水印 img_mark = img_mark.point(lambda i: round(i/85)*85) print equal(img_get,img_mark) return equal(img_get,img_mark) if __name__ == '__main__': print testWaterMarking('output.png','mark.jpg') 注 jpeg是有损压缩,中间存储要存为png等无损格式1