vue项目图片列表预览及图片增加水印

有一个列表详情页面,里面有图片,之前是点击图片进行预览
现在实现点击图片进行预览并加上水印效果

图片预览用的是vue的v-viewer插件
添加水印用的canvas添加水印

思路:一个列表详情可能有多张图片,列表返回的图片是服务器地址图片
利用canvas添加水印,第一步是把服务器地址图片转为base64图片,第二步是把base64图片进行canvas水印处理
第三步是把处理完的水印图片放到要预览的数组中

  1. 错误思路:第一次想的是点击预览的时候,拿到所有图片,然后把所有图片转为base64处理一下,在做水印处理,有个弊端,就是页面中
    如果5个图片,每次点击一次图片,都会把所有的图片处理下,每次会触发5次,这样点了5个会触发25次.

  2. 正确思路:第二次这么处理,拿到列表的时候,就先把所有图片base64处理一下,做水印处理,放在另外一个数组B中,然后预览的时候取这个B数组已经处理过的水印图片,这样只需处理5次即可.

//previewList图片数组列表
//previewShowList处理完的加水印的canvas图片列表 给预览用的

this.previewList.forEach((item) => {
    this.getBase64Image(item);
}),
getBase64Image(imgUrl) {
    const that = this;
    window.URL = window.URL || window.webkitURL;
    var xhr = new XMLHttpRequest();
    xhr.open("get", imgUrl, true);
    xhr.responseType = "blob";
    xhr.onload = function () {
        if (this.status == 200) {
            var blob = this.response;
            let oFileReader = new FileReader();
            oFileReader.onloadend = function (e) {
                // 此处拿到的已经是 base64的图片了
                let base64 = e.target.result;
                this.run(base64)
            };
            oFileReader.readAsDataURL(blob);
        }
    }
    xhr.send();
},
// 运行示例
run(imgUrl) {
    // 1.图片路径转成canvas
    const tempCanvas = await this.imgToCanvas(imgUrl);
    // 2.canvas添加水印
    const markText = '我是水印'
    const canvas = this.addWatermark(tempCanvas, markText);
    // 3.canvas转成img
    const img = this.convasToImg(canvas);
    // 查看效果
    this.previewShowList.push(img.src);
},
// 添加水印
async imgToCanvas(url) {
    // 创建img元素
    const img = document.createElement("img");
    img.src = url;
    img.setAttribute("crossOrigin", "anonymous"); // 防止跨域引起的 Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
    await new Promise((resolve) => (img.onload = resolve));
    // 创建canvas DOM元素,并设置其宽高和图片一样
    const canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.height;
    // 坐标(0,0) 表示从此处开始绘制,相当于偏移。
    canvas.getContext("2d").drawImage(img, 0, 0);
    return canvas;
},
/**
    * canvas添加水印
    * @param {canvas对象} canvas
    * @param {水印文字} text
    */
addWatermark(canvas, text) {
    const ctx = canvas.getContext("2d");
    ctx.rotate(50 * Math.PI / 180) // 水印旋转角度
    ctx.font = '15px Vedana'
    ctx.fillStyle = '#ccc'
    ctx.textAlign = 'center'
    ctx.textBaseline = 'Middle'
    let forIndex = canvas.width / 100 | 0
    for(let i = -10; i < 10; i++) {
        for(let j = -10; j < forIndex; j++) {
            ctx.fillText(text, 300 * j, 150 * i + 75)
        }
    }
    return canvas;
},

/**
* canvas转成img
* @param {canvas对象} canvas
*/
convasToImg(canvas) {
    // 新建Image对象,可以理解为DOM
    var image = new Image();
    // canvas.toDataURL 返回的是一串Base64编码的URL
    // 指定格式 PNG
    image.src = canvas.toDataURL("image/png");
    return image;
},
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值