欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue+Canvas制作簡易的水印添加器小工具

 更新時間:2022年06月08日 16:59:04   作者:錢林川  
隨著搬運(yùn)工的逐漸增加,原創(chuàng)作者的利益收到了極大的影響。所以給圖片或視頻加上水印顯得極其重要。本文分享一個由canvas和vue.js制作的圖片水印添加器,需要的可參考一下

前言

隨著搬運(yùn)工的逐漸增加,原創(chuàng)作者的利益收到了極大的影響.所以給圖片或視頻加上水印顯得極其重要,他可以有效的維護(hù)原創(chuàng)作者的版權(quán)防止盜版.本文分享一個由canvas和vue.js制作的圖片水印添加器。

效果展示

實現(xiàn)功能

自定義水印的文字及顏色,水印的位置,旋轉(zhuǎn)角度,大小,透明度,是否重復(fù)顯示,以及選擇為重復(fù)時可以選擇文字之間的水平間距和垂直間距,在設(shè)置為合適的圖片時點(diǎn)擊下載按鈕即可下載得到完成圖.如果覺得效果不好也可以點(diǎn)擊重置按鈕瞬間清屏.同時還支持logo圖水印。

實現(xiàn)思路

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

<!-- 引入樣式 -->
<link rel="stylesheet"  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">重新設(shè)置水印</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">旋轉(zhuǎn)  
                            <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>重復(fù)  
                            <el-select v-model="repetition" placeholder="請選擇" @change="loop">
                                <el-option label="不重復(fù)" :value="false"></el-option>
                                <el-option label="重復(fù)" :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.點(diǎn)擊按鈕后需要選擇上傳水印的圖片方法如下:

整體思路如下:

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
    },

下面先介紹一下項目中運(yùn)行到的一些函數(shù)方法:

(1)繪制背景函數(shù),先拿到頁面中cavans元素,運(yùn)用drawImage()畫出背景。

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

(2) 繪制字體水印,同理先拿到canvas元素, 運(yùn)用到的方法:

  • context.font:設(shè)置字體的大小。
  • context.fillStyle:設(shè)置字體的類型顏色。
  • repetition:判斷是否重復(fù) 。
  • globalAlpha:設(shè)置字體的透明度。
  • rotate:旋轉(zhuǎn)角度。
  • translate:偏移位置。
  • setposition()函數(shù):設(shè)置水印的位置,主要用到了canvas.width和canvas.height。
  • 中心點(diǎn)位置: 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) { //是否想要文字重復(fù),默認(rèn)不重復(fù)
        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)清屏函數(shù):如果在繪制過程中,對繪制的效果不滿意,想要重新繪制,就涉及到清屏操作,這里我是將輸入的文字(inputval)和選中的水?。╨ogo)設(shè)置為空再重新繪制, 代碼如下:

//重新設(shè)置
unset(){
    //輸入的文字
    this.inputval = null
    //選中的水印
    this.logo = null
    this.loop()
               },

(4)保存圖片代碼:繪制完成后就是保存圖片代碼,這里我是先創(chuàng)建了一個url元素用來存放下載的位置,文件名用new Date().getTime()+‘.png’ 這種形式來避免文件名重復(fù),當(dāng)我們下載完成之后創(chuàng)建的url并沒有被釋放,此時就需要使用 URL.revokeObjectURL()方法將內(nèi)存釋放掉,此處做了一個延遲,讓url內(nèi)存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)功能函數(shù):使用這種方法創(chuàng)建元素可以節(jié)約資源避免浪費(fèi)。

//----功能函數(shù)----
   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;
        }

初始界面:

點(diǎn)擊按鈕選擇圖片后:

總結(jié)

上面就是水印制作工具的全部過程了,最終效果跟上面一樣,主要就是運(yùn)用了canvas的一些屬性。

到此這篇關(guān)于Vue+Canvas制作簡易的水印添加器小工具的文章就介紹到這了,更多相關(guān)Vue Canvas水印添加器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue切換div顯示隱藏,多選,單選代碼解析

    Vue切換div顯示隱藏,多選,單選代碼解析

    這篇文章主要介紹了Vue切換div顯示隱藏,多選,單選代碼解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-07-07
  • vue 2.8.2版本配置剛進(jìn)入時候的默認(rèn)頁面方法

    vue 2.8.2版本配置剛進(jìn)入時候的默認(rèn)頁面方法

    今天小編就為大家分享一篇vue 2.8.2版本配置剛進(jìn)入時候的默認(rèn)頁面方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • vite打包去除console.log和debugge的方法實踐

    vite打包去除console.log和debugge的方法實踐

    本文主要介紹了vite打包去除console.log和debugge的方法實踐,vite 已經(jīng)將這個功能內(nèi)置了,所以我們只需要修改配置文件,下面就來介紹一下如何修改
    2023-12-12
  • vue的url請求圖片的問題及請求失敗解決

    vue的url請求圖片的問題及請求失敗解決

    這篇文章主要介紹了vue的url請求圖片的問題及請求失敗解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • vue發(fā)送ajax請求詳解

    vue發(fā)送ajax請求詳解

    如何利用vue進(jìn)行AJAX,其它vue本身不支持發(fā)送AJAX請求,需要使用vue-resource(vue1.0版本)或axios(vue2.0版本)第三方插件的支持才行
    2018-10-10
  • vue中路由重定向redirect問題

    vue中路由重定向redirect問題

    這篇文章主要介紹了vue中路由重定向redirect問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • 如何去除element-ui中table的hover效果

    如何去除element-ui中table的hover效果

    這篇文章主要介紹了如何去除element-ui中table的hover效果,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • vue組件引用另一個組件出現(xiàn)組件不顯示的問題及解決

    vue組件引用另一個組件出現(xiàn)組件不顯示的問題及解決

    這篇文章主要介紹了vue組件引用另一個組件出現(xiàn)組件不顯示的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue.js評論發(fā)布信息可插入QQ表情功能

    vue.js評論發(fā)布信息可插入QQ表情功能

    這篇文章主要為大家詳細(xì)介紹了vue.js評論發(fā)布信息可插入QQ表情功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • 詳解Vue2的diff算法

    詳解Vue2的diff算法

    這篇文章主要介紹了Vue2的diff算法的相關(guān)資料,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下
    2021-01-01

最新評論