This article shares the specific implementation code of adding watermarks to uploaded pictures in Vue for your reference. The specific content is as follows 1. Encapsulation and watermarking 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) } }) }) } 2. Use in the project <!-- Image Upload--> <div class="flex mt20" v-if="item.questionType === 4"> <van-uploader v-model="item.imgUpload" multiple="true" lazy-loading :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; //Image compression quality export default { methods: { // Before uploading async handleBeforeImgUpload(img, detail) { if (!img) { return } return new Promise(async (resolve, reject) => { if (Array.isArray(img)) { if (img.length > 5) { this.$toast('Upload up to 5 photos at a time, please upload in batches!') reject() } let blobs = [] for (const file of img) { // Images larger than 512k are compressed first if (file.size > 512 * 1024 && file.type.includes('image/')) { file = await this.compressor(file) } // Add watermark let blob = await addWaterMarker(file) blob.name = file.name blobs.push(blob) } resolve(blobs) } else { // Images larger than 512k should be compressed first 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) } }) }, //After uploading 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('Upload failed, only photos can be uploaded!') // Upload completed if (index === img.length - 1) { $loading.hide() } return //return in forEach is equivalent to continue } if (file.size > 1024 * 1024 * 10) { this.currentItem.imgUpload.splice(detail.index + index, 1) this.$toast('The file is too large, a single file cannot exceed 10M!') // Upload completed 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('Upload failed, please try again later!') console.error(error) } // Upload completed 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('Upload failed, only photos can be uploaded!') return } if (img.file.size >= 1024 * 1024 * 10) { this.currentItem.imgUpload.splice(detail.index, 1) $loading.hide() this.$toast('The file is too large and cannot exceed 10M!') return } // If it is larger than 512k, compress it first 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('Upload failed, please try again later!') console.error(error) } } } Thanks to Brother Long for his guidance; 3. The effects are as follows 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:
|
>>: Quickly solve the Chinese input method problem under Linux
1. Overview The information_schema database is th...
When I was printing for a client recently, he aske...
Table of contents Preface Example summary Preface...
Preface: Based on a recent medical mobile project...
Recently, when doing homework, I needed to nest a ...
MySQL Lock Overview Compared with other databases...
Preface Basically, programmers in the workplace u...
MySQL Introduction to MySQL MySQL was originally ...
Zero, Background I received a lot of alerts this ...
JS implements a hover drop-down menu. This is a s...
1. Execute SQL to view select @@session.sql_mode;...
Related articles: Beginners learn some HTML tags ...
Grouping and linking in MYSQL are the two most co...
1. Install dependency packages [root@localhost ~]...
Comprehensive Documentation github address https:...