vue3图片列表添加水印

·  阅读 76

ps:从后台获取到图片数组,前端给每个图片添加水印;用canvas绘制,我是在网上找了篇文章,原文是单个图片点击放大才是水印图片,我是需要拿到水印图片渲染出来,再因为我的工程是vue3所以稍微改动了一下;原文参考链接:blog.csdn.net/strongbuger…

最终效果

1660274315466.png

1. 页面html代码

循环数组图片,以及没有水印的时候,添加图片加载钟提示语;

 <div v-for="(item,index) in list" :key="index" class="phoneOnce">
    <div class="imgDiv">
        <img :src="item.pic" class="imgMain" v-if="item.showImg"/>
        <span v-else> 图片正在加载中...</span>
    </div>
    <div class="phoneName">
        {{item.name}}
    </div>    
</div>
复制代码

2. js代码

*因为是用canvas绘制图片,所以拿到的图片是需要有读写功能的;需要把权限放开
1.getBase64Image方法,先把图片链接变成base64
2.run方法,就是把图片和文字放入到canvas中,并调用方法得到法把水印的图片赋值到list中; 3.imgToCanvas图片绘制到canvas中; 4.addWatermark绘制水印文字;

<script setup>
import {ref,reactive,onMounted} from 'vue'
const text = ref('我是水印');//可以根据需要更改不同的文字
const list = reactive([
        {
            'pic':'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg',
            'name':'web-vivi'   
        },
        {
              'pic':'https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg',
            'name':'web-vivi'
        }              
    ])
//onMounted
onMounted(()=>{
   setTimeout(()=>{ //这里用setTimeout来模仿后台接口调用;
        list.map((item,index)=>{ 
            item.showImg = false;//图片赋值默认提示      
            getBase64Image(item.pic,index); //传入一个下标,下次赋值的时候才能找到这个下标
            return item;
        })
    },1000)
});
const getBase64Image = ((imgUrl,index)=>{ 
    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;
                run(base64,index) 
            };
            oFileReader.readAsDataURL(blob);
        }
    }
    xhr.send();
})
const run = async (imgUrl,index)=>{
    // 1.图片路径转成canvas
    const tempCanvas = await imgToCanvas(imgUrl);
    // 2.canvas添加水印
    const markText = text.value
    const canvas = addWatermark(tempCanvas, markText);
    // 3.canvas转成img
    const img = convasToImg(canvas);
    list[index].pic = img.src; // 把已经变成base64的图片赋值到数组中;  
}
// 添加水印
const  imgToCanvas= async (url)=> {
    // 创建img元素
    const img = document.createElement("img");
    img.src = url;
    img.setAttribute("crossOrigin", "anonymous"); // 防止跨域
    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
    */
const  addWatermark = (canvas, text)=>{
    const ctx = canvas.getContext("2d");
    ctx.rotate(50 * Math.PI / 180) // 水印旋转角度
    ctx.font = '30px Vedana'
    ctx.fillStyle = '#000'
    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
*/
const convasToImg=(canvas=> {
    // 新建Image对象,可以理解为DOM
    var image = new Image();
    // canvas.toDataURL 返回的是一串Base64编码的URL
    // 指定格式 PNG
    image.src = canvas.toDataURL("image/png");
    return image;
});
</script>
复制代码
分类:
前端
收藏成功!
已添加到「」, 点击更改