东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成

一、简朴水印(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<defaultSettings.watermark_rows;i++){y=defaultSettings.watermark_y+(defaultSettings.watermark_y_space+defaultSettings.watermark_height)*i;for(var j=0;j<defaultSettings.watermark_cols;j++){x=defaultSettings.watermark_x+(defaultSettings.watermark_width+defaultSettings.watermark_x_space)*j;var mask_div=document.createElement('div');mask_div.id='mask_div'+i+j;mask_div.appendChild(document.createTextNode(defaultSettings.watermark_txt));mask_div.style.webkitTransform="rotate(-"+defaultSettings.watermark_angle+"deg)";mask_div.style.MozTransform="rotate(-"+defaultSettings.watermark_angle+"deg)";mask_div.style.msTransform="rotate(-"+defaultSettings.watermark_angle+"deg)";mask_div.style.OTransform="rotate(-"+defaultSettings.watermark_angle+"deg)";mask_div.style.transform="rotate(-"+defaultSettings.watermark_angle+"deg)";mask_div.style.visibility="";mask_div.style.position="absolute";mask_div.style.left=x+'px';mask_div.style.top=y+'px';mask_div.style.overflow="hidden";mask_div.style.zIndex="9";mask_div.style.pointerEvents="none";mask_div.style.opacity=defaultSettings.watermark_alpha;mask_div.style.fontSize=defaultSettings.watermark_fontsize;mask_div.style.fontFamily=defaultSettings.watermark_font;mask_div.style.color=defaultSettings.watermark_color;mask_div.style.textAlign="center";mask_div.style.width=defaultSettings.watermark_width+'px';mask_div.style.height=defaultSettings.watermark_height+'px';mask_div.style.display="block";mask_div.style.fontWeight="900";oTemp.appendChild(mask_div)}};document.body.appendChild(oTemp)};watermark.load=function(settings){window.onload=function(){loadMark(settings)};window.onresize=function(){loadMark(settings)}};watermark.load({watermark_txt:"测试水印,saucxs,测试水印,songEagle,工号等"})})(window.watermark={});

(3)转变一下页面窗口大小,然后就能够看到我首页涌现如下图的水印,一层浅浅的水印

《东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成》

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

2、水印的优化

当然是需要运用者不晓得这个页面有水印,保证一些信息的平安性以及泄漏以后能够追踪到是谁在泄漏机密信息,他没有发觉到有水印,所以需要将水印调成通明度很低,如许运用者看不到水印,然则一旦运用者截图将图片宣布到互联网上,这时刻只需要将图片举行一些简朴操纵就能够让水印从新展现出来。

只需运用者不晓得有水印存在,如许就是从根本上加了水印,信息的源头上加了水印,确保信息的平安,以及泄漏以后的追踪。

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

《东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成》

把图片放到PS,我运用的是ps cs6内里,建一个空缺图层在上面,添补为黑色,操纵:如图所示背景色挑选黑色,然后按shift+f5,挑选背景色举行添补。

《东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成》

夹杂情势挑选正片叠底这一类的(也就是让亮的更亮,暗的更暗),一个个试。当我试到“实色夹杂”和“色彩加深”的时刻,水印就显现出来了。

哇,吓到我了,原本能够这么玩。

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完全代码

假如后续更新和优化的时刻,源码请看这个watermark-dom里的watermark.js文件

5、一个详细的例子

引入这个watermark.js的代码。

html代码

<html>
    <meta charset="utf-8">
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <script type="text/javascript" src="watermark.js"></script>
    <script type="text/javascript">
        watermark.load({ watermark_txt: "测试水印,1021002301,测试水印,SDAHJDBJJdjsfsc" });
    </script>
    
    <body>
        <div style="width:300px;height:300px;background-color: red; opacity:0.98;" onclick="alert(1);">test</div>
        <div style="width:300px;height:300px;background-color: blue;  opacity:0.9;" onclick="alert(2);">test</div>
        <a href="www.test.com"> baidu</a>
    </body>
</html>

结果如下图:

《东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成》

6、水印测试东西

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

watermark-dom的测试东西

包含,测试,重置,显现,随机,四个部份。

特征: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"></script>

第三步:在确保页面DOM加载终了以后,挪用watermark的load要领(手动加载):

   <script>watermark.load({ watermark_txt: "测试水印,1021002301,测试水印,100101010111101" })</script>

注重:我们供应了init要领,用来初始化水印,增加load和resize事宜

   <script>watermark.init({ watermark_txt: "测试水印,1021002301,测试水印,100101010111101" })</script>

7.2当地引入封装的js文件

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

npm install watermark-dom

第二步:引入水印模块:

import watermark from 'watermark-dom'
或许
var watermarkDom = require("watermark-dom")

第三步:在确保页面DOM加载终了以后,挪用watermark的load要领(手动加载):

   <script>watermark.load({ watermark_txt: "测试水印,1021002301,测试水印,100101010111101" })</script>

注重:我们供应了init要领,用来初始化水印,增加load和resize事宜

   <script>watermark.init({ watermark_txt: "测试水印,1021002301,测试水印,100101010111101" })</script>

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_anglewatermark_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,               //水印长度
});

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

《东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成》

所以平常先在watermark-dom的测试东西上,把需要设置的属性值,调试好以后在写入代码中,如许效力更高。

二、庞杂(频域体式格局图片兼并水印)

频域体式格局图片兼并水印,意义就是说,从图片编码里举行水印的增加,如许从最根本上处理图片的水印,而且水印的构成以后的图片是用肉眼和PS显现不出来的,只需经由历程反向编码让水印显现,如许就算是开辟职员也不会晓得这个图片是不是含有水印,只需开辟这个体系的职员晓得。

1、道理剖析

《东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成》

《东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成》

编码的目标有两个:

1、对水印加密,

2、二掌握水印能量的散布。

以下是频域体式格局图片兼并水印的试验。

(1)原图象。尺寸300*240 ,男人一枚,

《东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成》

(2)水印照片。

《东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成》

(3)水印编码。编码体式格局采纳随机序列编码,经由历程编码,水印散布到随机散布到各个频次,而且对水印举行了加密。

《东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成》

(4)原图象频域。阅历的是傅里恭弘=叶 恭弘变更,下图变更后的频域图象

《东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成》

(5)水印图象频域。阅历的是傅里恭弘=叶 恭弘变更,下图变更后的频域图象

《东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成》

(6)兼并水印和原图。以后,将叠加水印的频谱举行傅里恭弘=叶 恭弘逆变更,获得叠加数字水印后的图象,,将图象频域和水印编码举行兼并。看不出来已加了水印吧,

实际上,我们是把水印以噪声的情势增加到原图象中。

《东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成》

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

《东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成》

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

《东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成》

(9)下图是原图频谱竖过来的模样,其能量重要集合在低频。

那末,为何频谱发生了庞大的变化,而在空域却变化云云小呢?这是由于我们避开了图象的重要频次。

《东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成》

兼并以后

《东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成》

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

《东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成》

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

《东西系列--简朴水印(watermark-dom)和算法水印(频域体式格局图片兼并)完成》

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、频域体式格局图片兼并水印是一个从图片的编码体式格局举行合成水印,水印不可见,直接反向编码才够拿到水印,从最根本上处理了数据平安和数据泄漏后的追踪题目。

    原文作者:saucxs
    原文地址: https://segmentfault.com/a/1190000019195579
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞