前言 前段时间在写houdini学习之路的博文,这个过程中引用了大量的图片,我担心图片被人盗取,所以想要给所有的博客图片添加水印,这篇博文就应运而生了。
这次研究还延伸除了博客瘦身的方法,详情可以了解另一篇博文——博客瘦身方法。
最开始我是直接搜索js给图片添加水印的方法,有通过给图片添加div生成水印的,但是这种方案只是在网页上实现水印,用户下载图片水印就消失了,这样的方案指标不治本,所以我需要将水印合成到图片当中,获取合成后的图片地址。这之中有利用canvas和直接生成的链接方案。当然网上也有封装好的插件。
最开始我并不打算使用插件来完成的,但是canvas的方案实在让我头疼,不得已我只好去寻求插件来解决。
canvas的最大问题在于我无法将img标签替换为canvas,我在这地方卡壳了,所以就放弃了canvas方案。
利用插件生成图片水印 pa7/watermark.js 最开始在网上找到了watermark.js,看名字就知道这个东西铁定和水印有关的,但是这个脚本是很久没有更新了。官方给出的使用方法看得我不明不白,而且有些代码错误,而且实现不了效果。
相关链接
brianium/watermarkjs 后面我就去github上面找watermark,找个星星多的,就找到了另一个watermark.js脚本,然而这个也不好弄,官方的doc介绍不明不白的(bootstrap的脚本路径还是错误的),用得我很是不爽,还是实现不了效果。
相关链接
Img2Blob.js 这个工具也是在网上找的,感觉实现还算友好,单独的图片好像是可以的,但是博客上还是不行。
相关链接
lelinhtinh/watermark 终于在使用这个工具的时候,我发现博客之所以不行是因为要等待图片加载,需要加入setTimeout进行操作。后面这个插件就实现了效果。
相关链接
1 <script src ="/js/jquery.watermark.min.js" > </script >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 setTimeout (function ( ){ $('.fancy-ctn' ).each (function ( ){ $(this ).children ('img' ).watermark ({ text : 'FXTD-odyssey' , textSize :50 , textWidth : 300 , opacity : 0 , margin : 10 , done :function (imgURL ){ this .src =imgURL; $(this ).parent ().attr ('href' ,imgURL); } }); }) },500 )
总结 这是通过生成合成了水印的图片链接,将图片的src地址替换掉,从而实现效果,这样就不用去用canvas去替换img标签那么麻烦了。
效果虽然实现了,但是有个致命的问题。
如果博文的图片少还不是很明显,我Houdini系列中,有些博文一篇就有30多张图,打开之后要卡顿很久很久才能将水印生成出来,为此回想起canvas的快速实现效果,于是乎我重新去研究canvas的实现方案。
canvas生成图片水印 因为最开始我一直在寻找img替换为canvas的方法,但是并没有好的实现方案,网上的那些转换,在博客当中都不起作用。
所以经过水印插件的研究,我认为替换图片路径会是更好的方案,问题是图片地址要怎么生成出来。
经过不懈的努力,我找到了这篇博文
但是他实现的效果和我的大相径庭,我将它的代码复制了下来进行了魔改。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 setTimeout (function ( ){ $('.fancy-ctn' ).each (function ( ){ var scope = this ; Img _waterMark($(this ).children ().attr ('src' ),function (url ){ $(scope).children ('img' ).attr ('src' ,url); $(scope).attr ('href' ,url); }); }) },500 ) function Img_waterMark (imgPath,setImg ){ var src = imgPath; var canvas = document .createElement ('canvas' ); var logoText ='FXTD-odyssey' ; var context = canvas.getContext ('2d' ); var imgUpload = new Image (); imgUpload.src =src; imgUpload.onload = function ( ) { var width = imgUpload.width ; var height= imgUpload.height ; canvas.width = width; canvas.height = height; context.font ="50px 微软雅黑" ; context.fillStyle = "#fff" ; context.drawImage (imgUpload, 0 , 0 ,imgUpload.width ,imgUpload.height ,0 ,0 ,width,height); context.fillText (logoText,10 ,50 ); let url=canvas.toDataURL ("image/jpg" ); setImg (url); } }
图片加载完成才添加水印 使用setTimeout其实并不好,延迟的时间很难定夺,图片太多的话500毫秒可能也是不够的。
为了解决这个问题,我找了这篇博文
这样就实现了图片都加载完才去添加水印。
最后的代码汇总
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 var t_img; var isLoad = true ; isImgLoad (function ( ){ $('.fancy-ctn' ).each (function ( ){ var scope = this ; console .log ("test" ); Img _waterMark($(this ).children ().attr ('src' ),function (url ){ $(scope).children ('img' ).attr ('src' ,url); $(scope).attr ('href' ,url); }); }) }); function isImgLoad (callback ){ $('img' ).each (function ( ){ if (this .height === 0 ){ isLoad = false ; return false ; } }); if (isLoad){ clearTimeout (t_img); callback (); }else { isLoad = true ; t_img = setTimeout (function ( ){ isImgLoad (callback); },500 ); } } function Img_waterMark (imgPath,setImg ){ var src = imgPath; var canvas = document .createElement ('canvas' ); var logoText ='FXTD-odyssey' ; var context = canvas.getContext ('2d' ); var imgUpload = new Image (); imgUpload.src =src; imgUpload.onload = function ( ) { var width = imgUpload.width ; var height= imgUpload.height ; canvas.width = width; canvas.height = height; context.font ="50px 微软雅黑" ; context.fillStyle = "#fff" ; context.drawImage (imgUpload, 0 , 0 ,imgUpload.width ,imgUpload.height ,0 ,0 ,width,height); context.fillText (logoText,10 ,50 ); let url=canvas.toDataURL ("image/jpg" ); setImg (url); } }
总结 其实canvas的方案和插件的实现效率相差无几,而且在加载的过程中原图会暴露,不仅起不到保护作用,也让网页加载巨慢无比,因此,我最后不得不放弃这些js的实现方案,采用图床来添加水印。