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

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

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

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

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


vue实现上传图片添加水印
基于Typescript与Axios的接口请求管理详解
51自学网,即我要自学网,自学EXCEL、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。
京ICP备13026421号-1