频谱图水印matlab,插件系列--简单水印(watermark-dom)和算法水印(频域方式图片合并)实现...

本文介绍了网页水印插件watermark-dom的使用方法和原理,包括如何在页面上添加透明度极低的水印,以及通过调整透明度和颜色使其在截图后可通过后期处理显现。此外,还探讨了频域方式的图片水印技术,通过在图片编码中嵌入水印,达到不可见且难以去除的效果,确保数据安全和追溯性。
摘要由CSDN通过智能技术生成

插件github地址:https://github.com/saucxs/wat... 有详细的使用步骤,可以参考,不会用请留言,感觉可以,请给个星星。

一、简单水印(watermark-dom)

阿里巴巴内网的不可见水印用的是什么算法?

据说月饼事件截图的那位员工也被开除了?

下面的只是简单的加一个很浅的水印,实现起来很容易。

1、看看水印的效果

随便找一个网站,比如就找掘金的个人首页,

(1)F12检查模式,

(2)在console里粘贴下面的代码,

(function(watermark){window.watermarkdivs=[];var loadMark=function(settings){var defaultSettings={watermark_txt:"text",watermark_x:20,watermark_y:20,watermark_rows:0,watermark_cols:0,watermark_x_space:50,watermark_y_space:50,watermark_color:'#000000',watermark_alpha:0.005,watermark_fontsize:'18px',watermark_font:'微软雅黑',watermark_width:150,watermark_height:100,watermark_angle:15,watermark_bg_alpha:0.5};if(arguments.length===1&&typeof arguments[0]==="object"){var src=arguments[0]||{};for(key in src){if(src[key]&&defaultSettings[key]&&src[key]===defaultSettings[key])continue;else if(src[key])defaultSettings[key]=src[key]}}var oTemp=document.createDocumentFragment();if(window.watermarkdivs&&window.watermarkdivs.length>0){document.body.removeChild(document.getElementById("otdivid"));window.watermarkdivs=[]}var page_width=Math.max(document.body.scrollWidth,document.body.clientWidth);var page_height=Math.max(document.body.scrollHeight,document.body.clientHeight);var otdiv=document.getElementById("otdivid");if(defaultSettings.watermark_cols==0||(parseInt(defaultSettings.watermark_x+defaultSettings.watermark_width*defaultSettings.watermark_cols+defaultSettings.watermark_x_space*(defaultSettings.watermark_cols-1))>page_width)){defaultSettings.watermark_cols=parseInt((page_width-defaultSettings.watermark_x+defaultSettings.watermark_x_space)/(defaultSettings.watermark_width+defaultSettings.watermark_x_space));defaultSettings.watermark_x_space=parseInt((page_width-defaultSettings.watermark_x-defaultSettings.watermark_width*defaultSettings.watermark_cols)/(defaultSettings.watermark_cols-1))}if(defaultSettings.watermark_rows==0||(parseInt(defaultSettings.watermark_y+defaultSettings.watermark_height*defaultSettings.watermark_rows+defaultSettings.watermark_y_space*(defaultSettings.watermark_rows-1))>page_height)){defaultSettings.watermark_rows=parseInt((defaultSettings.watermark_y_space+page_height-defaultSettings.watermark_y)/(defaultSettings.watermark_height+defaultSettings.watermark_y_space));defaultSettings.watermark_y_space=parseInt(((page_height-defaultSettings.watermark_y)-defaultSettings.watermark_height*defaultSettings.watermark_rows)/(defaultSettings.watermark_rows-1))}var x;var y;for(var i=0;i

(3)改变一下页面窗口大小,然后就可以看到我首页出现如下图的水印,一层浅浅的水印

1460000019195582?w=1916&h=910

它的作用是在当前页面上增加了一个透明度只有0.005的很多的水印。水印内容“测试水印,saucxs,测试水印,songEagle,工号等”。

2、水印的优化

当然是需要使用者不知道这个页面有水印,保证一些信息的安全性以及泄露之后可以追踪到是谁在泄露机密信息,他没有发觉到有水印,所以需要将水印调成透明度很低,这样使用者看不到水印,但是一旦使用者截图将图片发布到互联网上,这时候只需要将图片进行一些简单操作就可以让水印重新显现出来。

只要使用者不知道有水印存在,这样就是从根本上加了水印,信息的源头上加了水印,确保信息的安全,以及泄露之后的追踪。

我们还是拿掘金的个人首页作为试验田。这回我们将水印的透明度调成0.004,水印字体颜色调成页面背景颜色(掘金的是#f4f5f5),然后截图(这回看不出来有水印吧)

1460000019195583?w=1349&h=551

把图片放到PS,我使用的是ps cs6里面,建一个空白图层在上面,填充为黑色,操作:如图所示背景色选择黑色,然后按shift+f5,选择背景色进行填充。

1460000019195584?w=1064&h=562

混合模式选择正片叠底这一类的(也就是让亮的更亮,暗的更暗),一个个试。当我试到“实色混合”和“颜色加深”的时候,水印就显示出来了。

哇,吓到我了,原来可以这么玩。

3、watermark-dom水印原理分析

通过js向html中一次性添加dom元素,所以我取名叫做watermark-dom,如果一旦知道有这个水印插件,使用者是可以手动将当前页面的水印dom删掉,这样也就是开发人员知道怎么弄,对于其他人员还是不知道如何去掉页面水印的。

3.1关键元素1--pointer-events:none

这个归功于css的属性,准确的说是css3的一个属性pointer-events,本来这个属性的而设计之初是为了--真正意义上的禁用元素,因为设置值为none的时候,这个元素是使用鼠标或者触摸感知不到的,可以称pointer-events为“元素虚化”。

支持浏览器:目前FireFox浏览器,Chrome都支持。Opera以及IE不支持。

该属性的缺点:

1、pointer-events:none影响触屏设备的滚动,如无线端页面等;

2、如果子元素设置了pointer-eventes: auto会导致滚动的时候页面闪动

3.2关键元素2--opacity属性

为什么这么说opacity属性,因为这个属性是对元素进行透明的设置,因为是水印,希望尽量不影响到正常页面的视觉体验。

支持浏览器:所有浏览器都支持 opacity 属性。注意:IE8以及更早的版本支持替代的filter属性。例如:filter:Alpha(opacity=50)。

在设置这个透明度的时候,经过测试发现,水印透明度,要求设置在大于等于0.005,因为比这个低的话,使用ps显现的时候效果不明显。

如果需要去尽量影藏水印,可以把水印的字体颜色和页面的背景颜色调成一致。

如果就要正常显示,尽量设置opactity的时候设置为大于等于0.005,一个性能和显示的平衡点。

4、附上watermark-dom完整代码

5、一个具体的例子

html代码

watermark.load({ watermark_txt: "测试水印,1021002301,测试水印,SDAHJDBJJdjsfsc" });

test
test

baidu

效果如下图:

1460000019195585?w=812&h=711

6、水印测试工具

写了插件,这个是测试地址

包括,测试,重置,显示,随机,四个部分。

特性:1、测试对水印参数属性,重置水印属性参数,显示此时的水印属性参数,随机产生水印属性参数;

2、水印按钮组是position值fixed,可以浮现在页面之上,不占字节。

3、对系统的各个部分页面进行水印的测试。

7、基础使用

7.1本地引入封装的js文件

只是简单的加一个很浅的水印,实现起来很容易。不需要引入jquery插件。

watermark.js是必须要引进的组件

第一步:获取组件方式:git clone https://github.com/saucxs/watermark-dom.git

第二步:clone后,在需要加水印的相关页面引入水印文件"watermark.js":

script type="text/javascript" src="./watermark.js">

第三步:在确保页面DOM加载完毕之后,调用watermark的load方法(手动加载):

注意:我们提供了init方法,用来初始化水印,添加load和resize事件

7.2本地引入封装的js文件

第一步:npm获取水印组件包:

npm install watermark-dom

第二步:引入水印模块:

import watermark from 'watermark-dom'

或者

var watermarkDom = require("watermark-dom")

第三步:在确保页面DOM加载完毕之后,调用watermark的load方法(手动加载):

注意:我们提供了init方法,用来初始化水印,添加load和resize事件

8、支持各种属性配置使用

watermark_id: 'wm_div_id', //水印总体的id

watermark_prefix: 'mask_div_id', //小水印的id前缀

watermark_txt:"测试水印", //水印的内容

watermark_x:20, //水印起始位置x轴坐标

watermark_y:20, //水印起始位置Y轴坐标

watermark_rows:0, //水印行数

watermark_cols:0, //水印列数

watermark_x_space:100, //水印x轴间隔

watermark_y_space:50, //水印y轴间隔

watermark_font:'微软雅黑', //水印字体

watermark_color:'black', //水印字体颜色

watermark_fontsize:'18px', //水印字体大小

watermark_alpha:0.15, //水印透明度,要求设置在大于等于0.005

watermark_width:100, //水印宽度

watermark_height:100, //水印长度

watermark_angle:15, //水印倾斜度数

watermark_parent_width:0, //水印的总体宽度(默认值:body的scrollWidth和clientWidth的较大值)

watermark_parent_height:0, //水印的总体高度(默认值:body的scrollHeight和clientHeight的较大值)

watermark_parent_node:null //水印插件挂载的父元素element,不输入则默认挂在body上

上面的属性都支持配置的,怎么使用呢?

基本山需要自己配置的属性:watermark_txt,watermark_color,watermark_fontsize,watermark_alpha,watermark_angle,watermark_width,watermark_height这7个属性一般是经常用到的,其他属性一般用的偏少。需要用到的就设置一下,不需要用到的就可以不设置,插件内部会有默认值的。

watermark.load({

watermark_txt:"测试水印,saucxs,测试水印,songEagle,工号等", //水印的内容

watermark_color:'#5579ee', //水印字体颜色

watermark_fontsize:'24px', //水印字体大小

watermark_alpha:0.5, //水印透明度,要求设置在大于等于0.005

watermark_angle:135, //水印倾斜度数

watermark_width:200, //水印宽度

watermark_height:200, //水印长度

});

这个设置之后后的页面如下图所示:

1460000019195586?w=1636&h=623

所以一般先在watermark-dom的测试工具上,把需要配置的属性值,调试好之后在写入代码中,这样效率更高。

二、复杂(频域方式图片合并水印)

频域方式图片合并水印,意思就是说,从图片编码里进行水印的添加,这样从最根本上解决图片的水印,而且水印的形成之后的图片是用肉眼和PS显示不出来的,只有通过反向编码让水印显示,这样就算是开发人员也不会知道这个图片是否含有水印,只有开发这个系统的人员知道。

1、原理分析

1460000019195587?w=906&h=127

1460000019195588?w=639&h=215

编码的目的有两个:

1、对水印加密,

2、二控制水印能量的分布。

以下是频域方式图片合并水印的实验。

(1)原图像。尺寸300*240 ,汉子一枚,

1460000019195589?w=601&h=408

(2)水印照片。

1460000019195590?w=293&h=111

(3)水印编码。编码方式采用随机序列编码,通过编码,水印分布到随机分布到各个频率,并且对水印进行了加密。

1460000019195591?w=606&h=420

(4)原图像频域。经历的是傅里叶变换,下图变换后的频域图像

1460000019195592?w=595&h=423

(5)水印图像频域。经历的是傅里叶变换,下图变换后的频域图像

1460000019195593?w=602&h=423

(6)合并水印和原图。之后,将叠加水印的频谱进行傅里叶逆变换,得到叠加数字水印后的图像,,将图像频域和水印编码进行合并。看不出来已经加了水印吧,

实际上,我们是把水印以噪声的形式添加到原图像中。

1460000019195594?w=604&h=409

(7)水印图与原图的残差(看不出来残差区别,需要调整对比度才能看得出来)

1460000019195595?w=611&h=412

(8)最终的均方差(MSE)和信噪比(PSNR)

1460000019195596?w=353&h=189

(9)下图是原图频谱竖过来的样子,其能量主要集中在低频。

那么,为什么频谱发生了巨大的变化,而在空域却变化如此小呢?这是因为我们避开了图像的主要频率。

1460000019195597?w=505&h=405

合并之后

1460000019195598?w=507&h=412

(10)水印提取是水印叠加的逆过程,

1460000019195599?w=624&h=182

(11)提取后,得到水印。

1460000019195600?w=615&h=417

2、附上可以还原实验的全部代码(matlab代码)

clc;clear;close all;

alpha = 1;

%% read data

im = double(imread('G:\2017学习\Work\图片水印\test.jpg'))/255;

mark = double(imread('G:\2017学习\Work\图片水印\watermark.png'))/255;

figure, imshow(im),title('original image');

figure, imshow(mark),title('watermark');

%% encode mark

imsize = size(im);

%random

TH=zeros(imsize(1)*0.5,imsize(2),imsize(3));

TH1 = TH;

TH1(1:size(mark,1),1:size(mark,2),:) = mark;

M=randperm(0.5*imsize(1));

N=randperm(imsize(2));

save('G:\2017学习\Work\图片水印\encode.mat','M','N');

for i=1:imsize(1)*0.5

for j=1:imsize(2)

TH(i,j,:)=TH1(M(i),N(j),:);

end

end

% symmetric

mark_ = zeros(imsize(1),imsize(2),imsize(3));

mark_(1:imsize(1)*0.5,1:imsize(2),:)=TH;

for i=1:imsize(1)*0.5

for j=1:imsize(2)

mark_(imsize(1)+1-i,imsize(2)+1-j,:)=TH(i,j,:);

end

end

figure,imshow(mark_),title('encoded watermark');

%% add watermark

FA=fft2(im);

figure,imshow(FA);title('spectrum of original image');

FB=FA+alpha*double(mark_);

figure,imshow(FB); title('spectrum of watermarked image');

FAO=ifft2(FB);

figure,imshow(FAO); title('watermarked image');

%imwrite(uint8(FAO),'watermarked image.jpg');

RI = FAO-double(im);

figure,imshow(uint8(RI)); title('residual');

%imwrite(uint8(RI),'residual.jpg');

xl = 1:imsize(2);

yl = 1:imsize(1);

[xx,yy] = meshgrid(xl,yl);

figure, plot3(xx,yy,FA(:,:,1).^2+FA(:,:,2).^2+FA(:,:,3).^2),title('spectrum of original image');

figure, plot3(xx,yy,FB(:,:,1).^2+FB(:,:,2).^2+FB(:,:,3).^2),title('spectrum of watermarked image');

figure, plot3(xx,yy,FB(:,:,1).^2+FB(:,:,2).^2+FB(:,:,3).^2-FA(:,:,1).^2+FA(:,:,2).^2+FA(:,:,3).^2),title('spectrum of watermark');

%% extract watermark

FA2=fft2(FAO);

G=(FA2-FA)/alpha;

GG=G;

for i=1:imsize(1)*0.5

for j=1:imsize(2)

GG(M(i),N(j),:)=G(i,j,:);

end

end

for i=1:imsize(1)*0.5

for j=1:imsize(2)

GG(imsize(1)+1-i,imsize(2)+1-j,:)=GG(i,j,:);

end

end

figure,imshow(GG);title('extracted watermark');

%imwrite(uint8(GG),'extracted watermark.jpg');

%% MSE and PSNR

C=double(im);

RC=double(FAO);

MSE=0; PSNR=0;

for i=1:imsize(1)

for j=1:imsize(2)

MSE=MSE+(C(i,j)-RC(i,j)).^2;

end

end

MSE=MSE/360.^2;

PSNR=20*log10(255/sqrt(MSE));

MSE

PSNR

三、总结

1、watermark-dom水印是一个简单的用于dom的水印,简单易上手,支持多选项配置。

2、频域方式图片合并水印是一个从图片的编码方式进行合成水印,水印不可见,直接反向编码才可以拿到水印,从最根本上解决了数据安全和数据泄露后的追踪问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值