前言

随着搬运工的逐渐增加,原创作者的利益收到了极大的影响.所以给图片或视频加上水印显得极其重要,他可以有效的维护原创作者的版权防止盗版.本文分享一个由canvas和vue.js制作的图片水印添加器。

效果展示

实现功能

自定义水印的文字及颜色,水印的位置,旋转角度,大小,透明度,是否重复显示,以及选择为重复时可以选择文字之间的水平间距和垂直间距,在设置为合适的图片时点击下载按钮即可下载得到完成图.如果觉得效果不好也可以点击重置按钮瞬间清屏.同时还支持logo图水印。

实现思路

1.首先要引入vue.js以及elementui组件和样式如下:

<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css" rel="external nofollow" />
<!-- 引入 Vue -->
<script src="https://unpkg.com/vue@next"></script>
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-plus"></script>

2.html代码如下:

<div id="app">
    <div class="home">
        <div class="mycontainer">
            <canvas id="canvasImg" @click="uploadfile()"></canvas>
            <div class="selectbox box" v-show="imgnode">
                <div style="max-width:330px">
                    <input type="text" class="canvastext" @input="addtext" v-model="inputval" placeholder="请输入水印文字"/>
                    水印颜色:<input type="color" style="margin-right:20px" class="colorselect" placeholder="" v-model="color" @change="loop">
                    取色器:<input type="color" class="colorselect">
                    <ul class="btns">
                        <li class="smallprant"><button @click="addlogo">上传水印或logo图</button></li>
                        <li><button @click="unset">重新设置水印</button></li>
                    </ul>
                </div>
                <div class="box">
                    <ul class="centerselect">
                        <li>位置  
                            <el-select v-model="position" placeholder="请选择" @change="loop">
                                <el-option label="中心" value="中心"></el-option>
                                <el-option label="左上" value="左上"></el-option>
                                <el-option label="上" value="上"></el-option>
                                <el-option label="右上" value="右上"></el-option>
                                <el-option label="右" value="右"></el-option>
                                <el-option label="右下" value="右下"></el-option>
                                <el-option label="下" value="下"></el-option>
                                <el-option label="左下" value="左下"></el-option>
                                <el-option label="左" value="左"></el-option>
                            </el-select>
                        </li>
                        <li class="rotate">旋转  
                            <el-select v-model="rotate" placeholder="请选择" @change="loop">
                                <el-option label="0°" :value="0"></el-option>
                                <el-option label="15°" :value="15"></el-option>
                                <el-option label="30°" :value="30"></el-option>
                                <el-option label="45°" :value="45"></el-option>
                                <el-option label="60°" :value="60"></el-option>
                            </el-select>
                        </li>
                        <li>重复  
                            <el-select v-model="repetition" placeholder="请选择" @change="loop">
                                <el-option label="不重复" :value="false"></el-option>
                                <el-option label="重复" :value="true"></el-option>
                            </el-select>
                        </li>
                    </ul>
                </div>
                <div class="box">
                    <span>x间距</span>
                    <div class="block" style="margin:10px 0 0 0;">
                        <el-slider v-model="value0" :step="1" :max="slidermax" @input="loop"></el-slider>
                    </div>
                    <span>y间距</span>
                    <div class="block" style="margin:10px 0 0 0;">
                        <el-slider v-model="value1" :step="1" :max="slidermax" @input="loop"></el-slider>
                    </div>
                    <span>大小</span>
                    <div class="block" style="margin:10px 0;">
                        <el-slider v-model="value2" :step="1" :max="slidermax" @input="loop"></el-slider>
                    </div>
                    <span>透明度</span>
                    <div class="block" style="margin:10px 0;">
                        <el-slider v-model="value3" :step="0.1" :max='1' @input="loop"></el-slider>
                    </div>
                </div>
            </div>
            <el-button v-show="imgnode" style="margin-top:10px;" @click="saveimg">保存图片到本地</el-button>
        </div>
    </div>
</div>

3.点击按钮后需要选择上传水印的图片方法如下:

整体思路如下:

loop () {
   this.clear()//1.清空画布
   if(this.imgnode)this.drawimg(this.imgnode)//2.判断是否上传了图片,有就绘制图片
   if(this.inputval)this.drawtext(this.inputval)//3.判断输入框是否有文字,有绘制文字
   if(this.logo)this.drawlogo(this.logo)//4.判断是否添加logo图片,有就绘制logo
    },

下面先介绍一下项目中运行到的一些函数方法:

(1)绘制背景函数,先拿到页面中cavans元素,运用drawImage()画出背景。

//绘制图片
drawimg(url){
   let canvas = document.getElementById('canvasImg')
   let context = canvas.getContext('2d')
   context.drawImage(url, 0, 0)
      },

(2) 绘制字体水印,同理先拿到canvas元素, 运用到的方法:

  • context.font:设置字体的大小。
  • context.fillStyle:设置字体的类型颜色。
  • repetition:判断是否重复 。
  • globalAlpha:设置字体的透明度。
  • rotate:旋转角度。
  • translate:偏移位置。
  • setposition()函数:设置水印的位置,主要用到了canvas.width和canvas.height。
  • 中心点位置: strarr = [canvas.width / 2, canvas.height / 2]。
  • 左上角位置: strarr = [0, 0]。

通过改变x,y将元素放置在画布各个位置,绘制logo水印同理。

//绘制字体水印
drawtext(value){
    let canvas = document.getElementById('canvasImg') //获取cavans
    let context = canvas.getContext('2d')
    let strarr = this.setposition()
    context.font = this.value2 "px '宋体'"
    context.fillStyle = this.color
   if (!this.repetition) { //是否想要文字重复,默认不重复
        context.save()
        context.globalAlpha = this.value3
        context.translate(strarr[0], strarr[1])
        context.rotate((Math.PI/180)*(this.rotate*1))
        context.translate(-strarr[0], -strarr[1])
        context.fillText(value, strarr[0], strarr[1] this.value2)
        context.restore()
          } else {
   for (let i=0 ; i < canvas.width ; i  = (this.value2*this.inputval.length  this.value0)) {
      for (let j = 0 ; j < canvas.height ; j  = (this.value2   this.value1)) {
          context.save()
          context.globalAlpha = this.value3
          context.translate(strarr[0] i, strarr[1] j)
          context.rotate((Math.PI/180)*(this.rotate*1))
          context.translate(-strarr[0]-i, -strarr[1]-j)
          context.fillText(value, (strarr[0]) i, (strarr[1]) j this.value2)
          context.restore()
                            }
                        }
                    }
                },

(3)清屏函数:如果在绘制过程中,对绘制的效果不满意,想要重新绘制,就涉及到清屏操作,这里我是将输入的文字(inputval)和选中的水印(logo)设置为空再重新绘制, 代码如下:

//重新设置
unset(){
    //输入的文字
    this.inputval = null
    //选中的水印
    this.logo = null
    this.loop()
               },

(4)保存图片代码:绘制完成后就是保存图片代码,这里我是先创建了一个url元素用来存放下载的位置,文件名用new Date().getTime() ‘.png’ 这种形式来避免文件名重复,当我们下载完成之后创建的url并没有被释放,此时就需要使用 URL.revokeObjectURL()方法将内存释放掉,此处做了一个延迟,让url内存5秒后被释放。

//保存图片到本地
saveimg () {
   let canvas = document.getElementById('canvasImg')
   canvas.toBlob(blob => {
   let url = URL.createObjectURL(blob)
   let save_link = document.createElement('a');
   save_link.href = url;
   save_link.download = new Date().getTime() '.png';
   let event = document.createEvent('MouseEvents');
   event.initEvent("click", true, false);
   save_link.dispatchEvent(event);
   setTimeout(() => {
      URL.revokeObjectURL(url)
             }, 5000);
           })
       },

(5)功能函数:使用这种方法创建元素可以节约资源避免浪费。

//----功能函数----
   loadImg (url) {
   const img = document.createElement('img')
   img.src = url
   return img
},

css代码如下:

*{
            margin: 0;
            padding: 0;
        }
        .title{
            font-size: 20px;
            margin: 30px;
            color:#888;
        }
        canvas{
            background-color: #ccc;
            max-width: 960px;
        }
        .cavansimg{
            width: 230px;
            height: 50px;
            background-color: #409EFF;
            border-radius: 5px;
            cursor: pointer;
        }
        .mycontainer {
            width: 960px;
            text-align: center;
            margin:0 auto;
            padding-bottom: 20px;
        }
        .textstyle{
            width: 100%;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .selectbox {
            display: flex;
            margin-top: 20px;
            justify-content: space-between;
        }
        .box{
            width: 100%;
            display: flex;
            justify-content: space-between;
            align-items: center;
            flex:1;
            color: #409EFF;
        }
        li {
            list-style: none;
        }
        .btns {
            display: flex;
            justify-content: space-between;
            margin-left: 20px;
        }
        .btns button {
            width: 120px;
            height: 50px;
            margin-right: 30px;
            border-radius: 10px;
            background-color: #409EFF;
            color: #fff;
            outline: none;
            border: none;
        }
        .colorselect {
            border-radius: 5px;
            width: 80px;
            height: 40px;
            outline: none;
            border: none;
        }
        .canvastext {
            height: 40px;
            width: 150px;
            border-radius: 5px;
            text-indent: 10px;
            border:1px solid #409EFF;
            border: none;
            outline: none;
        }
        .centerselect{
            margin:20 0;
            display: flex;
            justify-content: space-between;
            color: #409EFF;
        }
        .centerselect li {
            height: 50px;
            line-height: 50px;
        }
        span {
            display: inline-block;
        }
        .smallprant {
            position: relative;
        }
        html,body {user-select: none;}
        .block {
            width: 150px;
        }

初始界面:

点击按钮选择图片后:

总结

上面就是水印制作工具的全部过程了,最终效果跟上面一样,主要就是运用了canvas的一些属性。

到此这篇关于Vue Canvas制作简易的水印添加器小工具的文章就介绍到这了,更多相关Vue Canvas水印添加器内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

Vue+Canvas制作简易的水印添加器小工具的更多相关文章

  1. 微信小程序canvas实现水平、垂直居中效果

    这篇文章主要介绍了小程序中canvas实现水平、垂直居中效果,本文图文实例代码相结合给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

  2. H5最强接口之canvas实现动态图形功能

    这篇文章主要介绍了H5最强接口之canvas实现动态图形功能,需要的朋友可以参考下

  3. Canvas高级路径操作之拖拽对象的实现

    这篇文章主要介绍了Canvas高级路径操作之拖拽对象的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  4. canvas像素点操作之视频绿幕抠图

    这篇文章主要介绍了canvas像素点操作之视频绿幕抠图的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. html5利用canvas实现颜色容差抠图功能

    这篇文章主要介绍了html5利用canvas实现颜色容差抠图功能,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下

  6. canvas绘制视频封面的方法

    这篇文章主要介绍了canvas绘制视频封面的方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. HTML实现代码雨源码及效果示例

    这篇文章主要介绍了HTML实现代码雨源码及效果示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  8. 详解使用双缓存解决Canvas clearRect引起的闪屏问题

    这篇文章主要介绍了详解使用双缓存解决Canvas clearRect引起的闪屏问题的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  9. canvas实现按住鼠标移动绘制出轨迹的示例代码

    本篇文章主要介绍了canvas实现按住鼠标移动绘制出轨迹的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. 用canvas做一个DVD待机动画的实现代码

    这篇文章主要介绍了用canvas做一个DVD待机动画的实现代码的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部