阿里巴巴內網的不可見水印用的是什麼算法? 聽說月餅事件截圖的那位員工也被開除了?javascript
下面的只是簡單的加一個很淺的水印,實現起來很容易。css
隨便找一個網站,好比就找掘金的我的首頁,html
(1)F12檢查模式,java
(2)在console裏粘貼下面的代碼,node
(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)改變一下頁面窗口大小,而後就能夠看到我首頁出現以下圖的水印,一層淺淺的水印jquery
它的做用是在當前頁面上增長了一個透明度只有0.005的不少的水印。水印內容「測試水印,saucxs,測試水印,songEagle,工號等」。css3
固然是須要使用者不知道這個頁面有水印,保證一些信息的安全性以及泄露以後能夠追蹤到是誰在泄露機密信息,他沒有發覺到有水印,因此須要將水印調成透明度很低,這樣使用者看不到水印,可是一旦使用者截圖將圖片發佈到互聯網上,這時候只須要將圖片進行一些簡單操做就可讓水印從新顯現出來。git
只要使用者不知道有水印存在,這樣就是從根本上加了水印,信息的源頭上加了水印,確保信息的安全,以及泄露以後的追蹤。github
咱們仍是拿掘金的我的首頁做爲試驗田。這回咱們將水印的透明度調成0.004,水印字體顏色調成頁面背景顏色(掘金的是#f4f5f5),而後截圖(這回看不出來有水印吧)web
把圖片放到PS,我使用的是ps cs6裏面,建一個空白圖層在上面,填充爲黑色,操做:如圖所示背景色選擇黑色,而後按shift+f5,選擇背景色進行填充。
混合模式選擇正片疊底這一類的(也就是讓亮的更亮,暗的更暗),一個個試。當我試到「實色混合」和「顏色加深」的時候,水印就顯示出來了。
哇,嚇到我了,原來能夠這麼玩。
經過js向html中一次性添加dom元素,因此我取名叫作watermark-dom,若是一旦知道有這個水印插件,使用者是能夠手動將當前頁面的水印dom刪掉,這樣也就是開發人員知道怎麼弄,對於其餘人員仍是不知道如何去掉頁面水印的。
這個歸功於css的屬性,準確的說是css3的一個屬性pointer-events,原本這個屬性的而設計之初是爲了--真正意義上的禁用元素,由於設置值爲none的時候,這個元素是使用鼠標或者觸摸感知不到的,能夠稱pointer-events爲「元素虛化」。
支持瀏覽器:目前FireFox瀏覽器,Chrome都支持。Opera以及IE不支持。
該屬性的缺點:
一、pointer-events:none影響觸屏設備的滾動,如無線端頁面等;
二、若是子元素設置了pointer-eventes: auto會致使滾動的時候頁面閃動
爲何這麼說opacity屬性,由於這個屬性是對元素進行透明的設置,由於是水印,但願儘可能不影響到正常頁面的視覺體驗。
支持瀏覽器:全部瀏覽器都支持 opacity 屬性。注意:IE8以及更早的版本支持替代的filter屬性。例如:filter:Alpha(opacity=50)。
在設置這個透明度的時候,通過測試發現,水印透明度,要求設置在大於等於0.005,由於比這個低的話,使用ps顯現的時候效果不明顯。
若是須要去儘可能影藏水印,能夠把水印的字體顏色和頁面的背景顏色調成一致。
若是就要正常顯示,儘可能設置opactity的時候設置爲大於等於0.005,一個性能和顯示的平衡點。
若是後續更新和優化的時候,源碼請看這個watermark-dom裏的watermark.js文件
引入這個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>
複製代碼
效果以下圖:
寫了插件,這個是測試地址
包括,測試,重置,顯示,隨機,四個部分。
特性:一、測試對水印參數屬性,重置水印屬性參數,顯示此時的水印屬性參數,隨機產生水印屬性參數;
二、水印按鈕組是position值fixed,能夠浮如今頁面之上,不佔字節。
三、對系統的各個部分頁面進行水印的測試。
只是簡單的加一個很淺的水印,實現起來很容易。不須要引入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>
複製代碼
第一步: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>
複製代碼
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, //水印長度
});
複製代碼
這個設置以後後的頁面以下圖所示:
因此通常先在watermark-dom的測試工具上,把須要配置的屬性值,調試好以後在寫入代碼中,這樣效率更高。
頻域方式圖片合併水印,意思就是說,從圖片編碼裏進行水印的添加,這樣從最根本上解決圖片的水印,並且水印的造成以後的圖片是用肉眼和PS顯示不出來的,只有經過反向編碼讓水印顯示,這樣就算是開發人員也不會知道這個圖片是否含有水印,只有開發這個系統的人員知道。
編碼的目的有兩個:
一、對水印加密,
二、二控制水印能量的分佈。
如下是頻域方式圖片合併水印的實驗。
(1)原圖像。尺寸300*240 ,漢子一枚,
(2)水印照片。
(3)水印編碼。編碼方式採用隨機序列編碼,經過編碼,水印分佈到隨機分佈到各個頻率,而且對水印進行了加密。
(4)原圖像頻域。經歷的是傅里葉變換,下圖變換後的頻域圖像
(5)水印圖像頻域。經歷的是傅里葉變換,下圖變換後的頻域圖像
(6)合併水印和原圖。以後,將疊加水印的頻譜進行傅里葉逆變換,獲得疊加數字水印後的圖像,,將圖像頻域和水印編碼進行合併。看不出來已經加了水印吧,
實際上,咱們是把水印以噪聲的形式添加到原圖像中。
(7)水印圖與原圖的殘差(看不出來殘差區別,須要調整對比度才能看得出來)
(8)最終的均方差(MSE)和信噪比(PSNR)
(9)下圖是原圖頻譜豎過來的樣子,其能量主要集中在低頻。
那麼,爲何頻譜發生了巨大的變化,而在空域卻變化如此小呢?這是由於咱們避開了圖像的主要頻率。
合併以後
(10)水印提取是水印疊加的逆過程,
(11)提取後,獲得水印。
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
複製代碼
一、watermark-dom水印是一個簡單的用於dom的水印,簡單易上手,支持多選項配置。
二、頻域方式圖片合併水印是一個從圖片的編碼方式進行合成水印,水印不可見,直接反向編碼才能夠拿到水印,從最根本上解決了數據安全和數據泄露後的追蹤問題。