您当前的位置:首页 > 网站建设 > javascript
| php | asp | css | H5 | javascript | Mysql | Dreamweaver | Delphi | 网站维护 | 帝国cms | React | 考试系统 | ajax |

vue实现上传图片添加水印

51自学网 2022-05-02 21:31:45
  javascript

本文实例为大家分享了vue上传图片添加水印的具体实现代码,供大家参考,具体内容如下

1、封装添加水印方法

/** * 添加水印 * @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)      }    })  })}

2、项目中使用

<!-- 图片上传 --><div class="flex mt20" v-if="item.questionType === 4">  <van-uploader    v-model="item.imgUpload"    multiple="true"    lazy-load    :deletable="!isDisabled"    :disabled="isDisabled"    @delete="handleDeleteImg({ ...arguments, item })"    :before-read="handleBeforeImgUpload"    :after-read="handleAfterImgUpload"    @click.native="currentItem = item"  /></div>    <script>import {  getTaskDetail,  userExecute,  submitFlow,  rejectFlow,} from '@/api/myTask';import { uploadOSS } from '@/utils/oss';import { parseTime, addWaterMarker } from '@/utils';import { ImagePreview } from 'vant';import Compressor from 'compressorjs';const fileExtensions = ['xlsx', 'xls', 'docx', 'doc', 'pdf'];const quality = 0.2; //图片压缩质量export default {  methods: {  // 上传前   async handleBeforeImgUpload(img, detail) {      if (!img) {        return      }      return new Promise(async (resolve, reject) => {        if (Array.isArray(img)) {          if (img.length > 5) {            this.$toast('一次最多上传5张,请分批次上传!')            reject()          }          let blobs = []          for (const file of img) {            // 大于512k的图片则先压缩            if (file.size > 512 * 1024 && file.type.includes('image/')) {              file = await this.compressor(file)            }            // 添加水印            let blob = await addWaterMarker(file)            blob.name = file.name            blobs.push(blob)          }          resolve(blobs)        } else {          // 大于512k的图片则先压缩          if (img.size > 512 * 1024 && img.type.includes('image/')) {            img = await this.compressor(img)          }          const blob = await addWaterMarker(img)          blob.name = img.name          resolve(blob)        }      })    },        // 上传后    async handleAfterImgUpload(img, detail) {      try {        $loading.show()        if (Array.isArray(img)) {          img.forEach(async ({ file }, index) => {            if (!file.name || !file.type.includes('image/')) {              this.currentItem.imgUpload.splice(detail.index + index, 1)              this.$toast('上传失败,只能上传照片!')              // 上传完成              if (index === img.length - 1) {                $loading.hide()              }              return //forEach里的return相当于continue            }            if (file.size > 1024 * 1024 * 10) {              this.currentItem.imgUpload.splice(detail.index + index, 1)              this.$toast('文件太大,单个文件不能超过10M!')              // 上传完成              if (index === img.length - 1) {                $loading.hide()              }              return            }            try {              const { fileName, url } = await uploadOSS(file)              this.currentItem.answer.push({                url,              })            } catch (error) {              this.currentItem.imgUpload.splice(detail.index + index, 1)              this.$toast('上传失败,请稍后重试!')              console.error(error)            }            // 上传完成            if (index === img.length - 1) {              $loading.hide()            }          })        } else {          if (!img.file.type.includes('image')) {            this.currentItem.imgUpload.splice(detail.index, 1)            $loading.hide()            this.$toast('上传失败,只能上传照片!')            return          }          if (img.file.size >= 1024 * 1024 * 10) {            this.currentItem.imgUpload.splice(detail.index, 1)            $loading.hide()            this.$toast('文件太大,不能超过10M!')            return          }          // 大于512k则先压缩          let file = img.file          const { fileName, url } = await uploadOSS(file)          this.currentItem.answer.push({            url,          })          $loading.hide()        }      } catch (error) {        this.currentItem.imgUpload.splice(detail.index, 1)        $loading.hide()        this.$toast('上传失败,请稍后重试!')        console.error(error)      }    } }

感谢龙哥的指导;

3、效果如下

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


配置vue全局方法的两种方式实例
vue实现上传图片添加水印(升级版)
51自学网,即我要自学网,自学EXCEL、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。
京ICP备13026421号-1