<>快速使用

用 idea 打开 first.html,也就是起一个前端项目,直接打开会报跨域错误。

打开后,选择自己想查看的图片。这里以第二张图片甘雨为例,打开后会到达二级页面,二级页面包括了四张图片:

这四张图片以此表示了:原图、带明水印的图、数字水印、带暗水印的图。

点击最后一张图,会解析出明水印。

<>代码解析

二级界面文件夹下,有各个 html文件,一个css文件,一个 js 文件。

每个 html中都会链接到 css和 js 文件,html 中原本都只有一个 img 标签。css 文件没什么,就是规约了图片的大小。重点在 js 文件中。

waterMark.js 中的主体部分规定了两个全局变量,并执行了 run 方法。
var darkCanvas; var created=0; run();
接下来请看 run 方法。
async function run() { const url =
document.getElementsByClassName("img")[0].src; const img =
document.createElement("img"); img.src = url; img.crossOrigin='Anonymous';
await new Promise((resolve) => (img.onload = resolve)); let canvas =
document.createElement("canvas"); canvas.width = img.width * 400 / img.height;
canvas.height = 400; //可见水印 bright(canvas,img);
document.body.appendChild(document.createElement("br")); //黑底白字展示水印 let
waterMarkCanvas=waterMark(canvas); //展示不可见水印 dark(canvas,img,waterMarkCanvas); }
* run 方法会得到那张图片的 src 目录,然后试图加载这张图片,并且新建一个画布,规定画布的宽度和高 度和该图片一样。
* 然后再调用 bright 方法,得到一个明水印的图片。然后在后面加上一个换行(为了美观)。
* 然后再调用 waterMark 方法,将数字水印显示出来,并得到数字水印的画布。
* 最后调用 dark 方法,得到一个暗水印的图片。
接下来请看 bright 方法:
function bright(canvas,img) { let ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, canvas.width, canvas.height); ctx.fillStyle = "#FFF";
ctx.font = "24px 黑体"; ctx.fillText("191250025丁笑宇", 20, 350); draw(canvas); }
bright 方法将图片画在画布上,并给画布的上下文加上了一些设置,然后调用 draw 方法,把画布当做图片输出。

接下来请看 draw 方法:
function draw(canvas) { let img = new Image(); img.src =
canvas.toDataURL("image/png"); document.body.appendChild(img); }
draw 方法很简单,把画布当做图片输出,并放在当前 body 最后一个元素后面。

接下来请看 waterMark 方法:
function waterMark(canvas) { let ctx=canvas.getContext("2d");
ctx.fillStyle="#000"; ctx.fillRect(0,0,canvas.width,canvas.height);
ctx.fillStyle = "#FFF"; ctx.font = "24px 黑体"; ctx.fillText("191250025丁笑宇", 20,
350); draw(canvas); return canvas; }
和 bright 方法差不多,直接将画布设置成全黑,然后在上面绘制水印即可。

接下来请看 dark 方法:
function dark(canvas,img,waterMarkCanvas) { let
temp=waterMarkCanvas.getContext("2d").getImageData(0,0,canvas.width,canvas.heigh
t).data; canvas.getContext("2d").drawImage(img, 0, 0, canvas.width,
canvas.height); let
digits=canvas.getContext("2d").getImageData(0,0,canvas.width,canvas.height);
for (let i=0; i<digits.data.length; i=i+4) { if (temp[i] === 0) { } } }
canvas.getContext("2d").putImageData(digits,0,0); draw(canvas); let
images=document.body.getElementsByTagName("img"); let
image=images[images.length-1]; image.addEventListener("click", unload);
darkCanvas=canvas; }
首先获得了水印画布和图片画布的 image 信息。我们注意到,图片中一个像素点对应了数组中四个数,
在水印画布中,如果某个点不属于水印,则这个点就是(0,0,0,255)。考虑到两张画布的大小一致,我 们可以做这样的记录: 倘若水印画布某个点的第一个值是
0,则将图片画布上对应位置的那个点的第一个 值置为偶数,否则将那个对应位置的那个点的第一个值置为奇数。 这样处理过后,我们判断图片画布上
的每一个点对应的第一个值的奇偶性,奇数表示是水印位置,偶数表示不是水印位置。

然后把处理过的数据画出来,并且给这张图片加上点击的监听器,绑定了 unload 这个方法,然后记录下 当前的这个画布。

接下来请看 unload 方法:
function unload() { if (created===1) { return; } let
ctx=darkCanvas.getContext("2d"); let
digits=ctx.getImageData(0,0,darkCanvas.width,darkCanvas.height); for (let i=0;
i<digits.data.length; i=i+4) { if (digits.data[i] % 2 === 1) { digits.data[i] =
digits[i + 1] = digits[i + 2] = digits[i + 3] = ; } }
ctx.putImageData(digits,0,0); draw(darkCanvas); created=1; }
首先判断如果已经解码过了,就不会再解码。

然后我们对于 image 信息,判断每一个像素点的第一个数的奇偶性。如果是奇数,表示是水印位,就把这个像素点的四个值全部变成 255。

技术
©2019-2020 Toolsou All rights reserved,
C语言——qsort函数CSS实现溢出显示省略号网络层协议——ICMP协议C语言小游戏-俄罗斯方块Qt入门教程【基础控件篇】QCalendarWidget日历控件用python来控制wifi连接vue中input框只能输入数字Python内置函数C语言数据结构-顺序表删除重复V2.0.0abaqus质量缩放系数取值_ABAQUS的质量缩放