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

Solve the problem of docker images disappearing

1. Mirror images disappear in 50 and 93 [root@h50...

Implementation of multi-site configuration of Nginx on Mac M1

Note: nginx installed via brew Website root direc...

Detailed explanation of the underlying encapsulation of Java connection to MySQL

This article shares the Java connection MySQL und...

How to install FastDFS in Docker

Pull the image docker pull season/fastdfs:1.2 Sta...

Sending emails in html is easy with Mailto

Recently, I added a click-to-send email function t...

How to install pyenv under Linux

Prerequisites Need to install git Installation St...

JavaScript implements page scrolling animation

Table of contents Create a layout Add CSS styles ...

Windows 10 installation vmware14 tutorial diagram

Software Download Download software link: https:/...

Tips for viewing History records and adding timestamps in Linux

Tips for viewing History records and adding times...

React+ts realizes secondary linkage effect

This article shares the specific code of React+ts...

Analysis of the implementation of MySQL statement locking

Abstract: Analysis of two MySQL SQL statement loc...

Details about the like operator in MySQL

1. Introduction When filtering unknown or partial...

Example of making XML online editor using js

Table of contents Preface The need for online XML...

Vue.$set failure pitfall discovery and solution

I accidentally found that Vue.$set was invalid in...