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

實現(xiàn)功能
自定義水印的文字及顏色,水印的位置,旋轉(zhuǎn)角度,大小,透明度,是否重復(fù)顯示,以及選擇為重復(fù)時可以選擇文字之間的水平間距和垂直間距,在設(shè)置為合適的圖片時點擊下載按鈕即可下載得到完成圖.如果覺得效果不好也可以點擊重置按鈕瞬間清屏.同時還支持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.點擊按鈕后需要選擇上傳水印的圖片方法如下:
整體思路如下:
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
},下面先介紹一下項目中運行到的一些函數(shù)方法:
(1)繪制背景函數(shù),先拿到頁面中cavans元素,運用drawImage()畫出背景。
//繪制圖片
drawimg(url){
let canvas = document.getElementById('canvasImg')
let context = canvas.getContext('2d')
context.drawImage(url, 0, 0)
},(2) 繪制字體水印,同理先拿到canvas元素, 運用到的方法:
- context.font:設(shè)置字體的大小。
- context.fillStyle:設(shè)置字體的類型顏色。
- repetition:判斷是否重復(fù) 。
- globalAlpha:設(shè)置字體的透明度。
- rotate:旋轉(zhuǎn)角度。
- translate:偏移位置。
- setposition()函數(shù):設(shè)置水印的位置,主要用到了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) { //是否想要文字重復(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)和選中的水印(logo)設(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é)約資源避免浪費。
//----功能函數(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;
}初始界面:

點擊按鈕選擇圖片后:

總結(jié)
上面就是水印制作工具的全部過程了,最終效果跟上面一樣,主要就是運用了canvas的一些屬性。
到此這篇關(guān)于Vue+Canvas制作簡易的水印添加器小工具的文章就介紹到這了,更多相關(guān)Vue Canvas水印添加器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
el-table樹形數(shù)據(jù)量過大,導(dǎo)致頁面卡頓問題及解決
這篇文章主要介紹了el-table樹形數(shù)據(jù)量過大,導(dǎo)致頁面卡頓問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04
vue項目中常見的三種文件類型在線預(yù)覽實現(xiàn)(pdf/word/excel表格)
最近在項目中要做一個pdf在線預(yù)覽的功能,索性給大家整理個全面的,這篇文章主要給大家介紹了關(guān)于vue項目中常見的三種文件類型在線預(yù)覽實現(xiàn)的相關(guān)資料,文件類型分別是pdf/word文件/excel表格,需要的朋友可以參考下2022-05-05
vue-router如何實時動態(tài)替換路由參數(shù)(地址欄參數(shù))
這篇文章主要介紹了vue-router如何實時動態(tài)替換路由參數(shù)(地址欄參數(shù)),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09
Vue reactive函數(shù)實現(xiàn)流程詳解
一個基本類型的數(shù)據(jù),想要變成響應(yīng)式數(shù)據(jù),那么需要通過ref函數(shù)包裹,而如果是一個對象的話,那么需要使用reactive函數(shù),這篇文章主要介紹了Vue reactive函數(shù)2023-01-01

