• 前端和算法实现:给网站上加上自己的水印(简单+复杂)


    watermark插件的github地址:https://github.com/saucxs/watermark

    有详细的使用步骤,可以参考,不会用请留言,感觉可以,请给个星星。

    sau交流学习社区(首发):https://www.mwcxs.top/page/452.html

    一、简单

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

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

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

    浏览器终端下粘贴下面的代码,

     
     

    这样就可以加水印了。我选择了百度的首页,好像百度对这个有防护。

          它的作用是在当前页面上增加了一个透明度只有0.005的很多的水印。水印内容“测试水印,1021002301,测试水印,DAHJDBJJdjsfsc
     
     
    使用QQ截图,这样一点也看不出来,有水印。
     
     
     
     
     
     
     
     
     
     
    现在把图片放到PS里面,建一个图层在上面。全部填充为黑色,混合模式选择正片叠底这一类的(也就是让亮的更亮,暗的更暗),一个个试。。
     
     
    当我试到“实色混合”和“颜色加深”的时候,水印就显示出来了。

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

     watermark-dom的js源码:
     
     
     
    (function(watermark){
        window.watermarkdivs = [];
        // 加载水印
        var loadMark = function(settings) {
                var defaultSettings={
                    watermark_txt:"text",
                    watermark_x:20,//水印起始位置x轴坐标
                    watermark_y:20,//水印起始位置Y轴坐标
                    watermark_rows:0,//水印行数
                    watermark_cols:0,//水印列数
                    watermark_x_space:50,//水印x轴间隔
                    watermark_y_space:50,//水印y轴间隔
                    watermark_color:'#000000',//水印字体颜色
                    watermark_alpha:0.005,//水印透明度,小于等于0.003,不可恢复到水印。
                    watermark_fontsize:'18px',//水印字体
                    watermark_font:'微软雅黑',//水印字体
                    watermark_150,//水印宽度
                    watermark_height:100,//水印长度
                    watermark_angle:15,//水印倾斜度数
                    // watermark_bg_color:'yellow',
                    watermark_bg_alpha:0.5 //加透明度导致隐形水印无法读取
                    
                };
                //采用配置项替换默认值,作用类似jquery.extend
                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");
    
                //如果将水印列数设置为0,或水印列数设置过大,超过页面最大宽度,则重新计算水印列数和水印x轴间隔
                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));
                }
                //如果将水印行数设置为0,或水印行数设置过大,超过页面最大长度,则重新计算水印行数和水印y轴间隔
                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));
                        //设置水印div倾斜显示
                        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.border="solid #eee 1px";
                        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: "测试水印,1021002301,测试水印,SDAHJDBJJdjsfsc" });
    })(window.watermark = {});

    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="300px;height:300px;background-color: red; opacity:0.98;" onclick="alert(1);">test</div>
            <div style="300px;height:300px;background-color: blue;  opacity:0.9;" onclick="alert(2);">test</div>
            <a href="www.test.com"> baidu</a>
        </body>
    </html>

     

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

    http://www.mwcxs.top/static/testTool/index.html

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

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

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

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

    二、复杂

    频域制定数字盲水印

    信号是有频率的,一个信号可以看做是无数个不同阶的正弦信号的的叠加。
    F(omega)=int_{-infty }^{+infty }  f(t)e^{-iomega t}dt
    上式为傅里叶变换公式,f(t)是指时域信号(对于信号我们说时域,因为是与时间有关的,而图像我们往往说空域,与空间有关),omega 是指频率。

    1、编码的目的有二,一是对水印加密,二控制水印能量的分布。以下是叠加数字盲水印的实验。

    (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图片水印 est.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

      

  • 相关阅读:
    word设置的密码忘了怎么办?
    Navicat Report Viewer 设置 HTTP 的方法
    如何处理Navicat Report Viewer 报表
    excel密码忘记了怎么办
    Beyond Compare文本比较搜索功能详解
    Popular Cows POJ
    Problem B. Harvest of Apples HDU
    网络流模型整理
    The Shortest Statement CodeForces
    Vasya and Multisets CodeForces
  • 原文地址:https://www.cnblogs.com/chengxs/p/6762380.html
Copyright © 2020-2023  润新知