背景
有的時候我們需要在上傳圖片中新增一些水印標識,然後上傳至伺服器
效果圖
程式碼
需求:
-
- 點選直接預覽圖片,而不需要使用dialog
-
- 上傳圖片新增水印後才預覽圖片
- 上傳圖片檔案新增水印。使用watermarkjs庫轉換
- 將新增水印的圖片轉換成base64,更新預覽圖片的內容,否則預覽的圖片還是舊的
- 儲存新增水印後的檔案
- 自行上傳伺服器....
<template>
<div class="app">
<el-upload
action=""
list-type="picture-card"
:multiple="true"
:on-change="handleUploadChange"
:auto-upload="false"
>
<i slot="default" class="el-icon-plus"></i>
<div slot="file" slot-scope="{ file }">
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
<span class="el-upload-list__item-actions">
<span
class="el-upload-list__item-preview"
@click="handlePictureCardPreview(file)"
>
<i class="el-icon-zoom-in"></i>
<!-- <el-image
style="width: 100px; height: 100px"
:src="dialogImageUrl"
:preview-src-list="[dialogImageUrl]"
>
</el-image> -->
</span>
<span class="el-upload-list__item-delete" @click="handleRemove(file)">
<i class="el-icon-delete"></i>
</span>
</span>
</div>
</el-upload>
<!--
預覽圖片方式1:使用dialog方式
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="" />
</el-dialog> -->
<!-- 預覽圖片方式2:使用image-viewer -->
<el-image-viewer
v-if="imgViewerVisible"
:url-list="imgList"
:on-close="closeImgViewer"
/>
<div class="demo" ref="demoRef"></div>
</div>
</template>
<script>
import watermark from 'watermarkjs'
import ElImageViewer from 'element-ui/packages/image/src/image-viewer'
export default {
components: {
ElImageViewer,
},
data() {
return {
dialogImageUrl: '',
dialogVisible: false,
imgViewerVisible: false,
imgList: [],
}
},
methods: {
handlePictureCardPreview(file) {
// this.dialogImageUrl = file.url
// this.dialogVisible = true
this.imgViewerVisible = true
this.imgList = [file.url]
// 解決預覽放大後滾動滑鼠頁面跟著滾動的問題
const m = (e) => {
e.preventDefault()
}
document.body.style.overflow = 'hidden'
document.addEventListener('touchmove', m, false) // 禁止頁面滑動
},
closeImgViewer() {
this.imgViewerVisible = false
const m = (e) => {
e.preventDefault()
}
document.body.style.overflow = 'auto'
document.removeEventListener('touchmove', m, true)
},
handleRemove(file) {
console.log(file)
},
handleUploadChange(file, fileList) {
// console.log('file:', file)
// console.log('fileList:', fileList)
const upload_file = file.raw
// 1. 新增單個水印
// watermark([upload_file])
// .image(
// watermark.text.upperRight(
// 'watermark.js',
// '48px Josefin Slab',
// '#fff',
// 0.5,
// 48
// )
// )
// .then((img) => {
// img.style.width = '300px'
// img.style.height = 'auto'
// this.$refs.demoRef.append(img)
// })
// 2. 新增多個水印
// watermark([upload_file])
// .image(
// watermark.text.upperRight(
// '呵呵呵',
// '48px Josefin Slab',
// '#fff',
// 0.5,
// 48
// )
// )
// .render()
// .image(
// watermark.text.upperLeft(
// '哈哈哈',
// '48px Josefin Slab',
// '#fff',
// 0.5,
// 48
// )
// )
// .then((img) => {
// img.style.width = '300px'
// img.style.height = 'auto'
// this.$refs.demoRef.append(img)
// })
// 3. 自定義新增水印位置,比如:設定在右上角
// @param {HTMLCanvasElement} canvas
// @param {TextMetrics} metrics
// @param {CanvasRenderingContex2D} context - context of the canvas
// 設定水印的x座標
var x = function (canvas, metrics, context) {
// 微調,比如:-20 根據實際調整
return canvas.width - metrics.width - 20
}
// 設定水印的y座標
var y = function (canvas, metrics, context) {
return metrics.hangingBaseline + 10
}
watermark([upload_file])
.image(
watermark.text.atPos(
x,
y,
'上傳時間:2024-05-08 22:40:10',
'48px sans-serif',
'#fff',
0.8
)
)
.then((img) => {
// img.style.width = '300px'
// img.style.height = 'auto'
this.$refs.demoRef.append(img)
// 將base64轉檔案形式
const watermark_file = this.dataURLtoFile(img.src, file.name)
// 下載檔案
// this.downloadFile(watermark_file)
this.transformFileToBase64(watermark_file, file)
})
},
// 將base64轉檔案
dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], filename, { type: mime })
},
// 下載檔案
downloadFile(file) {
let aTag = document.createElement('a') //建立一個a標籤
aTag.download = file.name
let href = URL.createObjectURL(file) //獲取url
aTag.href = href
aTag.click()
URL.revokeObjectURL(href) //釋放url
},
// 將水印檔案轉換成base64,然後修改原有file物件的url,這樣保證預覽時圖片的url是帶有水印的
transformFileToBase64(watermark_file, file) {
return new Promise((resolve, reject) => {
// 讀取檔案
const reader = new FileReader()
//readAsDataURL()方法: 讀取檔案內容,結果用data:url的字串形式表示
reader.readAsDataURL(watermark_file)
// 讀取成功回撥
reader.onload = () => {
file.url = reader.result
}
})
},
},
}
</script>
<style lang="less" scoped></style>
第三方庫watermarkjs
連結:https://brianium.github.io/watermarkjs/docs.html#image
參考文件
- FileReader()讀取檔案、圖片上傳預覽
https://www.cnblogs.com/libo-web/p/15766987.html - Element-ui中 使用圖片檢視器(el-image-viewer) 預覽圖片
https://juejin.cn/post/7084856145277354020