vue2 添加水印组件,canvas水印

功能:1、角标水印  2、全屏水印  3、添加了elementui 图片预览 4、是否可复制图片
注意:elementui的图片预览组件需要自己去nodemodels里找
 

 import ElImageViewer from "element-ui/packages/image/src/image-viewer"

组件使用方法:

 <ImageWatermark
 :imageUrl="item.images"
 :watermarkText="item.nickname"
 :paste="item.gif"
 watermarkType="fullscreen"
 >

</ImageWatermark>

组件内部代码:注意element图片预览组件的引用
 

<template>
    <div class="image-with-watermark" :class="watermarkedImageUrls.length > 1 ? 'itemimgs':'itemimg'">
        <template v-for="item in watermarkedImageUrls" >
            <el-image 
            :src="item" 
            :key="item"
            ref="imageViewer"
            @click="handleImageClick"
            @contextmenu="handleRightClick($event,item.copy_paste)"
           >
            <div slot="placeholder" class="image-slot">
                加载中<span class="dot">...</span>
            </div>
          </el-image>
        </template>
        <!-- <el-dialog
        :visible.sync="dialogVisible"
        :lock-scroll="false"
        :append-to-body="true"
        >
        <img class="img" :src="itemImages" alt="" srcset="">
        
        </el-dialog> -->
        <el-image-viewer
        v-if="previewVisible"
        hide-on-click-modal
        teleported
        ref="viewer"
        :on-close="closePre"
        
        :url-list="watermarkedImageUrls">

        </el-image-viewer>
    </div>
  </template>
  
  <script>
    import html2canvas from 'html2canvas';
  import ElImageViewer from "element-ui/packages/image/src/image-viewer";
  export default {
    props: {
      imageUrl: Array,//需要添加水印的图片数组
      watermarkText: String,//水印文字
      watermarkType: String, //水印类型:'fullscreen'为全屏水印 'corner'为角标水印
      width: {
        type: [Number, String],
        default: "100%", 
      },
      height: {
        type: [Number, String],
        default: "auto", 
      },
      list:Array,
      paste:String//是否禁止复制图片 
    },
    data() {
      return {
        imageDataUrl: "",
        dialogVisible:false,
        containerWidth: this.width, 
        containerHeight: this.height, 
        imgList:this.list,
        watermarkedImageUrls:[],
        itemImages:'',
        previewVisible:false
      };
    },
    components: {
        ImagePreviewDialog:()=> import('@/components/ImagePreviewDialog/ImagePreviewDialog.vue'),
        ElImageViewer,
    },
    computed: {
      imageUrlProp() {
        return this.imageUrl;
      },
    },
    watch: {
      imageUrls: "addWatermarkToImages",
      watermarkType: "loadImage",
      width: "updateContainerWidth",
      height: "updateContainerHeight",
      height: "updateContainerHeight",
      list: "updateImgList",
    },
    mounted() {
      this.addWatermarkToImages();
    },
    methods: {
        handleRightClick(event,index){
            console.log('禁止右击',this.paste);
            if(this.paste == 1){
                event.preventDefault()
                this.$message({
                message: '无法保存,创作者已开启了版权保护!',
                type: 'warning'
                });
            }
        },
        async closePre() {
            this.previewVisible = false
        },
        async handleImageClick() {
            this.previewVisible = true
        },
        async addWatermarkToImages() {
        const watermarkedImageUrls = [];

        for (const imageUrl of this.imageUrlProp) {
            const watermarkedImageUrl = await this.addWatermarkToImage(imageUrl);
            // console.log('watermarkedImageUrl',watermarkedImageUrl);
            watermarkedImageUrls.push(watermarkedImageUrl);
        }

        this.watermarkedImageUrls = watermarkedImageUrls;
        },
      async addWatermarkToImage(imageUrl) {
        return new Promise((resolve) => {
            const image = new Image();
            image.crossOrigin = "Anonymous";
    
            image.src = imageUrl;
    
            image.onload = () => {
            
            const canvas = document.createElement("canvas");
            const ctx = canvas.getContext("2d");
    
            canvas.width = image.width;
            canvas.height = image.height;
    
            ctx.drawImage(image, 0, 0);
    
            const watermarkFontSize = Math.min(image.width / 10, image.height / 10, 40); // 根据图片大小定义水印文字的大小
            if (this.watermarkType === "fullscreen") {
            //全屏水印
            this.drawFullScreenWatermark(ctx,watermarkFontSize);
            } else if (this.watermarkType === "corner") {
              // 角标水印
            ctx.font = `${watermarkFontSize}px Arial`;
            // const angle = -Math.PI / 8;
            // ctx.translate(30, ctx.canvas.height - 30);
            // ctx.rotate(angle);
            ctx.fillStyle = "rgba(255, 255, 255, 0.5)";
            ctx.fillText(this.watermarkText, 10, canvas.height - 10);
            }

                const watermarkedImageUrl = canvas.toDataURL();
                
                resolve(watermarkedImageUrl);
            };
        });
      },
      //全屏水印
        drawFullScreenWatermark(ctx,watermarkFontSize) {
            const watermarkText = this.watermarkText;
            const angle = Math.PI / 12; 
            const numRows = 3; 
            const numColumns = 3; 
            const cellWidth = ctx.canvas.width / numColumns;
            const cellHeight = ctx.canvas.height / numRows;

            ctx.fillStyle = "rgba(255, 255, 255, 0.5)";

            for (let row = 0; row < numRows; row++) {
                for (let col = 0; col < numColumns; col++) {
                const x = col * cellWidth;
                const y = row * cellHeight;

                ctx.save(); 

                ctx.translate(x + cellWidth / 2, y + cellHeight / 2); 
                ctx.rotate(angle); 
                ctx.font = `${watermarkFontSize}px Arial`;

               
                ctx.fillText(watermarkText, -ctx.measureText(watermarkText).width / 2, 0);

                ctx.restore(); 
                }
            }
        },
      updateContainerWidth() {
        this.containerWidth = this.width;
      },
      updateContainerHeight() {
        this.containerHeight = this.height;
      },
      updateImgList() {
        this.imgList = this.list;
      },
    },
  };
  </script>
  
  <style scoped lang="scss">
  ::v-deep .el-image-viewer__canvas > img{
    pointer-events: none;
    -webkit-touch-callout: none; /*禁止长按链接与图片弹出菜单*/
-webkit-user-select: none; /*禁止选中文本*/
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
  }
  ::v-deep .el-dialog{
    width: 80%;
    background: transparent;
    margin: 0;
    box-shadow: none;
    margin: 0 auto;
  }
  ::v-deep .el-dialog__body{
    display: flex;
    justify-content: center;
}
@media all and (max-width: 1100px) {
    .img{
        max-width: 80%;
    }
  }
  @media all and (min-width: 1100px) {
    ::v-deep .el-dialog{
        display: flex;
        justify-content: center;
    }
    ::v-deep .el-dialog__body{
        width: 50%;
    }
    .img{
        width: 100%;
    }
    ::v-deep .el-dialog{
        width: 50%;
        background: transparent;
        margin: 0;
        box-shadow: none;
        margin: 0 auto;
    }
  }


.itemimgs{
    ::v-deep .el-image{
            width: 98px !important;
            height: 98px !important;
            margin: 0 7px 7px 0;
            border-radius: 4px;
            overflow: hidden;
    }
   
}
.itemimg{
    ::v-deep .el-image{

        max-width: 226px;
        max-height: 300px;
    }
}
  .image-with-watermark {
    display: inline-block;
    position: relative;
    overflow: hidden;
  }
  </style>
  

效果图:

注意!!!!!!!!!!!!!!!!!!!!!!!!!!
因为图片是canvas重画的所以在本地会显示不出来有跨域问题,需要布在服务器内!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,针对你的问题,我可以给你提供一些思路和参考方法: 1. 在 Vue 页面中引入 html2canvas 库,并使用其中的 toDataURL 方法将页面截图生成 Base64 图片数据。 2. 使用 Canvas 在图片上添加水印。 3. 可以添加多个水印,需要调整水印的位置和大小。 4. 最后将添加水印后的图片保存或上传到服务器。 下面是一个简单的示例代码,仅供参考: ``` <template> <div> <button @click="generateImage">生成图片</button> </div> </template> <script> import html2canvas from 'html2canvas'; export default { methods: { async generateImage() { const canvas = await html2canvas(document.querySelector('#target'), { useCORS: true, }); const ctx = canvas.getContext('2d'); const img = new Image(); img.src = canvas.toDataURL(); // 添加水印 img.onload = () => { // 添加第一个水印 ctx.font = 'bold 20px Arial'; ctx.fillStyle = 'rgba(255, 255, 255, 0.6)'; ctx.fillText('watermark1', 50, 50); // 添加第二个水印 ctx.font = 'bold 30px Arial'; ctx.fillStyle = 'rgba(255, 255, 255, 0.6)'; ctx.fillText('watermark2', 200, 200); // 将添加水印后的图片保存到本地 const link = document.createElement('a'); link.download = 'image.png'; link.href = canvas.toDataURL(); link.click(); }; }, }, }; </script> ``` 这里添加的两个水印只是示例,你可以根据需要添加更多的水印,并调整水印的位置和大小。同时,你需要注意浏览器的跨域问题,如果出现跨域问题,可以使用 `useCORS` 参数解决。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值