vue实现上传图片添加水印(升级版)

vue项目实现上传图片添加水印升级版,供大家参考,具体内容如下

封装水印方法

/**

* 添加水印

* @param {blob} file

* @param {string} el

* @returns {Promise}

*/

export async function addWaterMarker(file, el = '#markImg') {

return new Promise(async (resolve, reject) => {

try {

// 先压缩和旋转图片

file = await compressor(file)

// 将文件blob转换成图片

let img = await blobToImg(file)

// 创建canvas画布

let canvas = document.createElement('canvas')

canvas.width = img.naturalWidth

canvas.height = img.naturalHeight

let ctx = canvas.getContext('2d')

// 填充上传的图片

ctx.drawImage(img, 0, 0, canvas.width, canvas.height)

// 生成水印图片

const markEle = document.querySelector(el)

const markWidth = markEle.clientWidth

const scale = canvas.width * 0.25 / markWidth

// 先缩放水印再转成图片

markEle.style.transform = `scale(${scale})`

const markImg = await htmlToCanvas(markEle)

// 填充水印

ctx.drawImage(markImg, canvas.width - markImg.width - 15 * scale, canvas.height - markImg.height - 15 * scale, markImg.width, markImg.height)

// 将canvas转换成blob

canvas.toBlob(blob => resolve(blob))

} catch (error) {

reject(error)

}

})

}

function blobToImg(blob) {

return new Promise((resolve, reject) => {

let reader = new FileReader()

reader.addEventListener('load', () => {

let img = new Image()

img.src = reader.result

img.addEventListener('load', () => resolve(img))

})

reader.readAsDataURL(blob)

})

}

export function htmlToCanvas(el, backgroundColor = 'rgba(0,0,0,.1)') {

return new Promise(async (resolve, reject) => {

try {

const markImg = await html2canvas(el, {

scale: 2, //此处不使用默认值window.devicePixelRatio,需跟移动端保持一致

allowTaint: false, //允许污染

useCORS: true,

backgroundColor //'transparent' //背景色

})

resolve(markImg)

} catch (error) {

reject(error)

}

})

}

/**

* 压缩和旋转图片

* @param {blob} file

* @param {number} quality 压缩比例

* @param {number} maxWidth

* @returns {Promise}

*/

export function compressor(file, quality = 0.6, maxWidth = 750) {

return new Promise(resolve => {

new Compressor(file, {

maxWidth,

quality,

success: resolve,

error(err) {

console.log(err.message)

}

})

})

}

页面中使用水印并压缩图片

<template>

<div>

<el-upload

action=""

:headers="uploadProps.headers"

list-type="picture-card"

:show-file-list="false"

:http-request="fnUploadRequest"

:on-success="handleSuccess"

:before-upload="handleUpload"

accept=".png,.jpg,.jpeg,.gif,.webp"

>

<div class="flex-center">

<slot></slot>

</div>

</el-upload>

<!-- 图片上传水印 -->

<div id="markImg">

<div class="logo">

<img src="@/assets/img/icon-logo.png" />

文本文本

</div>

<p>

{{ parseTime(fileDate, '{y}-{m}-{d} {h}:{i}:{s}') }} 周{{

parseTime(fileDate, '{a}')

}}

</p>

<p>{{ executor }}</p>

</div>

</div>

</template>

<script>

import {

getAccessToken,

getRefreshToken,

getAccessTokenTTL

} from '@/utils/auth'

import { uploadOSS } from '@/utils/ossImage'

import { parseTime, compressor, addWaterMarker } from '@/utils'

export default {

name: 'index',

props: {

needWaterMark: {

type: Boolean,

default: false

},

executor: {

type: String,

default: ''

}

},

data() {

return {

fileDate: new Date()

}

},

created() {

this.parseTime = parseTime

},

computed: {

userAccountID() {

return this.$store.state.user.userAccountID

},

uploadProps() {

return {

// action: `${process.env.VUE_APP_BASE_API}/api/image/upload`,

headers: {

// 接口可能要带token: "",

Authorization: getAccessToken()

},

data: {}

}

}

},

methods: {

// beforeUpload_u(file, fileList){

// // console.log(file, fileList);

// var testmsg = file.name.substring(file.name.lastIndexOf('.') + 1)

// const extension = testmsg === 'png' || testmsg === 'jpg' || testmsg === 'jpeg' || testmsg === 'gif' || testmsg === 'webp'

// const isLimit10M = file.size / 1024 / 1024 < 10

// var bool = false;

// if(extension && isLimit10M){

// bool = true;

// } else {

// bool = false;

// }

// if(!extension) {

// this.$message.error('请上传图片格式文件!');

// return bool;

// }

// if(!isLimit10M) {

// this.$message.error('上传失败,不能超过10M!');

// return bool;

// }

// return bool;

// },

// handleSuccess(res) {

// console.log(res);

// if (res.code == 0) {

// this.$emit('imgData', res.item);

// this.$message.success('上传图片成功!');

// } else {

// this.$message.error('上传图片失败!');

// }

// },

// handleError(err){

// this.$message.error('上传图片失败!');

// },

// 上传图片判断

handleUpload(file, fileList) {

var testmsg = file.name.substring(file.name.lastIndexOf('.') + 1)

const extension =

testmsg.toLowerCase() === 'png' ||

testmsg.toLowerCase() === 'jpg' ||

testmsg.toLowerCase() === 'jpeg' ||

testmsg.toLowerCase() === 'gif' ||

testmsg.toLowerCase() === 'webp'

const isLimit10M = file.size / 1024 / 1024 < 10

var bool = false

if (extension && isLimit10M) {

bool = true

} else {

bool = false

}

if (!extension) {

this.$message.error('请上传图片格式文件!')

return bool

}

if (!isLimit10M) {

this.$message.error('上传失败,不能超过10M!')

return bool

}

return bool

},

// 上传图片

async fnUploadRequest(options) {

try {

let file = options.file // 拿到 file

this.fileDate = file.lastModifiedDate

// 压缩图片

if (file.size > 512 * 1024 && file.type.includes('image/')) {

file = await compressor(file)

}

// 添加水印

if (this.needWaterMark) {

const fileName = file.name

file = await addWaterMarker(file, '#markImg')

file.name = fileName

}

let res = await uploadOSS(file)

// 返回的就是图片地址

this.$emit('imgData', res)

this.$message.success('上传图片成功!')

} catch (e) {

console.log(e)

this.$message.error('上传图片失败!请重新上传')

}

},

//图片上传成功回调

handleSuccess(res) {

// console.log(res);

if (res) {

this.$emit('imgData', res)

}

}

}

}

</script>

<style lang="scss" scoped>

::v-deep .el-upload,

::v-deep .el-upload--picture-card {

// width: 120px;

height: 24px;

height: 0;

border: none;

line-height: 0;

display: block;

background: #f5f6fb;

}

// ::v-deep .el-upload{

// width: 50px;

// }

.img-cont {

width: 50px;

height: 24px;

background: #f5f6fb;

.img-icon {

color: #ccc;

}

.img-text {

font-size: 12px;

height: 24px;

color: #000;

}

}

#markImg {

position: absolute;

left: -9999999px;

text-align: right;

padding: 10px 15px;

.logo {

font-weight: 600;

font-size: 15px;

color: #ffffff;

display: flex;

height: 21px;

align-items: center;

justify-content: flex-end;

img {

height: 21px;

margin-right: 5px;

}

}

p {

margin-top: 6px;

color: #ffffff;

font-size: 12px;

font-weight: 400;

}

}

</style>

水印方法更新版

/**

* 压缩和旋转图片

* @param {blob} file

* @param {number} quality 压缩比例

* @param {number} maxWidth

* @returns {Promise}

*/

export function compressor(file, drew, maxWidth = 750, quality = 0.6) {

return new Promise(resolve => {

new Compressor(file, {

strict: false,

maxWidth,

quality,

drew,

success: resolve,

error(err) {

console.log(err.message)

}

})

})

}

/**

* 添加水印

* @param {blob} file

* @param {string} el

* @returns {Promise}

*/

export async function addWaterMarker(file, el = '#brandMarkImg', direction = 'rightDown') {

return new Promise(async (resolve, reject) => {

try {

const maxWidth = 750

const img = await blobToImg(file)

const imgWidth = img.naturalWidth > maxWidth ? maxWidth : img.naturalWidth

// 生成水印图片

const markEle = document.querySelector(el)

const scale = imgWidth * 0.25 / markEle.clientWidth

// 先缩放水印再转成图片

markEle.style.transform = `scale(${scale})`

const markImg = await htmlToCanvas(markEle)

// 先压缩和旋转图片

file = await compressor(file, (context, canvas) => {

if(direction == 'rightDown'){

// 填充水印 右下角

context.drawImage(markImg, canvas.width - markImg.width - 15 * scale, canvas.height - markImg.height - 15 * scale, markImg.width, markImg.height)

} else {

// 填充水印 左下角

context.drawImage(markImg, 15 * scale, canvas.height - markImg.height - 15 * scale, markImg.width, markImg.height)

}

}, maxWidth)

resolve(file)

} catch (error) {

reject(error)

}

})

}

function blobToImg(blob) {

return new Promise((resolve, reject) => {

let reader = new FileReader()

reader.addEventListener('load', () => {

let img = new Image()

img.src = reader.result

img.addEventListener('load', () => resolve(img))

})

reader.readAsDataURL(blob)

})

}

export function htmlToCanvas(el, backgroundColor = 'rgba(0,0,0,.1)') {

return new Promise(async (resolve, reject) => {

try {

const markImg = await html2canvas(el, {

scale: 2,

allowTaint: false, //允许污染

useCORS: true,

backgroundColor //'transparent' //背景色

})

resolve(markImg)

} catch (error) {

reject(error)

}

})

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是 vue实现上传图片添加水印(升级版) 的全部内容, 来源链接: utcz.com/p/239702.html

回到顶部