通过web前端实现水印制作

快速使用

用 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

首先获得了水印画布和图片画布的 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

首先判断如果已经解码过了,就不会再解码。

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

你可能感兴趣的:(前端,html,小程序,前端,vue.js)