Vue realizes adding watermark to uploaded pictures (upgraded version)

Vue realizes adding watermark to uploaded pictures (upgraded version)

The vue project implements an upgraded version of adding watermarks to uploaded pictures for your reference. The specific contents are as follows

Encapsulation watermark method

/**
 * Add watermark * @param {blob} file
 * @param {string} el
 * @returns {Promise}
 */
export async function addWaterMarker(file, el = '#markImg') {
  return new Promise(async (resolve, reject) => {
    try {
      // Compress and rotate the image first file = await compressor(file)
      // Convert the file blob to an image let img = await blobToImg(file)

      // Create a canvas let canvas = document.createElement('canvas')
      canvas.width = img.naturalWidth
      canvas.height = img.naturalHeight
      let ctx = canvas.getContext('2d')

      // Fill the uploaded image ctx.drawImage(img, 0, 0, canvas.width, canvas.height)

      // Generate watermark image const markEle = document.querySelector(el)
      const markWidth = markEle.clientWidth
      const scale = canvas.width * 0.25 / markWidth
      // Scale the watermark first and then convert it to an image markEle.style.transform = `scale(${scale})`
      const markImg = await htmlToCanvas(markEle)

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

      //Convert canvas into 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, //The default value window.devicePixelRatio is not used here, it needs to be consistent with the mobile end allowTaint: false, //Allow pollution useCORS: true,
        backgroundColor //'transparent' //background color})
      resolve(markImg)
    } catch (error) {
      reject(error)
    }
  })
}

/**
 * Compress and rotate images * @param {blob} file
 * @param {number} quality compression ratio * @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)
      }
    })
  })
}

Use watermarks and compress images in pages

<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>
    <!-- Image upload watermark-->
    <div id="markImg">
      <div class="logo">
        <img src="@/assets/img/icon-logo.png" />
        Text text</div>
      <p>
        {{ parseTime(fileDate, '{y}-{m}-{d} {h}:{i}:{s}') }} Week {{
          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: {
          // The interface may require a 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('Please upload a picture format file!');
    // return bool;
    // }
    // if(!isLimit10M) {
    // this.$message.error('Upload failed, cannot exceed 10M!');
    // return bool;
    // }
    // return bool;
    // },
    // handleSuccess(res) {
    // console.log(res);
    // if (res.code == 0) {
    // this.$emit('imgData', res.item);
    // this.$message.success('Upload image successfully!');
    // } else {
    // this.$message.error('Failed to upload image!');
    // }
    // },
    // handleError(err){
    // this.$message.error('Failed to upload image!');
    // },

    // Upload picture judgment 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('Please upload a picture format file!')
        return bool
      }
      if (!isLimit10M) {
        this.$message.error('Upload failed, cannot exceed 10M!')
        return bool
      }
      return bool
    },
    // Upload image async fnUploadRequest(options) {
      try {
        let file = options.file // Get file
        this.fileDate = file.lastModifiedDate
        // Compress the image if (file.size > 512 * 1024 && file.type.includes('image/')) {
          file = await compressor(file)
        }
        // Add watermarkif (this.needWaterMark) {
          const fileName = file.name
          file = await addWaterMarker(file, '#markImg')
          file.name = fileName
        }
        let res = await uploadOSS(file)
        // What is returned is the image address this.$emit('imgData', res)
        this.$message.success('Upload image successfully!')
      } catch (e) {
        console.log(e)
        this.$message.error('Failed to upload the image! Please upload again')
      }
    },
    //Image upload successful callback 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> 

Updated version of watermark method

/**
 * Compress and rotate images * @param {blob} file
 * @param {number} quality compression ratio * @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)
      }
    })
  })
}

/**
 * Add watermark * @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

      // Generate watermark image const markEle = document.querySelector(el)
      const scale = imgWidth * 0.25 / markEle.clientWidth
      // Scale the watermark first and then convert it to an image markEle.style.transform = `scale(${scale})`
      const markImg = await htmlToCanvas(markEle)

      // Compress and rotate the image first file = await compressor(file, (context, canvas) => {
        if(direction == 'rightDown'){
          // Fill the lower right corner of the watermark context.drawImage(markImg, canvas.width - markImg.width - 15 * scale, canvas.height - markImg.height - 15 * scale, markImg.width, markImg.height)
        } else {
          // Fill the lower left corner of the watermark 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, //Allow pollution useCORS: true,
        backgroundColor //'transparent' //background color})
      resolve(markImg)
    } catch (error) {
      reject(error)
    }
  })
}

The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM.

You may also be interested in:
  • Vue implements adding watermark to uploaded pictures
  • How to use pictures and picture watermarks with hidden text information in Vue
  • Vue implements adding watermark effect to the page
  • Vue integrates PDF.js to implement PDF preview and add watermark steps
  • Vue implements page watermark function
  • Three ways to upload pictures using Vue
  • The Uploader of Vue+Vant on the mobile terminal realizes the functions of uploading, compressing and rotating pictures
  • Vue+elementUI implements form and image upload and verification function example
  • vue+elementUI realizes the picture upload function
  • Based on VUE, select and upload pictures and display them on the page (pictures can be deleted)

<<:  Quickly solve the Chinese input method problem under Linux

>>:  Solution to the problem that Navicat cannot remotely connect to MySql server

Recommend

How to implement digital paging effect code and steps in CSS

A considerable number of websites use digital pagi...

Detailed explanation of whereis example to find a specific program in Linux

Linux finds a specific program where is The where...

Analysis of several situations where MySQL index fails

1. Best left prefix principle - If multiple colum...

Detailed explanation of MySQL information_schema database

1. Overview The information_schema database is th...

Vue implements a small countdown function

Countdown function needs to be implemented in man...

Notes on the MySQL database backup process

Today I looked at some things related to data bac...

How to deploy Go web applications using Docker

Table of contents Why do we need Docker? Docker d...

What does mysql database do?

MySQL is a relational database management system....

How to uninstall MySQL 5.7.19 under Linux

1. Find out whether MySQL was installed before Co...

Using CSS3 to achieve transition and animation effects

Why should we use CSS animation to replace JS ani...

How to implement Mysql scheduled tasks under Linux

Assumption: The stored procedure is executed ever...

MySQL 8.0.20 compressed version installation tutorial with pictures and text

1. MySQL download address; http://ftp.ntu.edu.tw/...

Detailed analysis of each stage of nginx's http request processing

When writing the HTTP module of nginx, it is nece...

JavaScript singleton mode to implement custom pop-up box

This article shares the specific code of JavaScri...