vue之原生上傳圖片加水印并壓縮圖片大小方式
更新時(shí)間:2025年01月24日 16:41:32 作者:一朵野花壓海棠
文章介紹了如何使用Vue原生上傳圖片,并在圖片上添加水印并壓縮圖片大小,首先,安裝了相應(yīng)的插件并進(jìn)行封裝,然后,介紹了添加水印的方法和上傳圖片的過程,最后,作者分享了自己的經(jīng)驗(yàn),并希望對(duì)大家有所幫助
vue原生上傳圖片加水印并壓縮圖片大小
安裝相應(yīng)插件
npm i -S compressorjs npm i -S html2canvas
封裝添加水印的方法
import Compressor from "compressorjs"; import html2canvas from "html2canvas"; /** * 壓縮和旋轉(zhuǎn)圖片 * @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 = "#markImg", direction = "rightDown") { return new Promise(async (resolve, reject) => { try { const maxWidth = 750; const img = await blobToImg(file); console.log(img.naturalWidth); const imgWidth = img.naturalWidth > maxWidth ? maxWidth : img.naturalWidth; // 生成水印圖片 const markEle = document.querySelector(el); const scale = (imgWidth * 0.25) / markEle.clientWidth; // 先縮放水印再轉(zhuǎn)成圖片 markEle.style.transform = `scale(${scale})`; const markImg = await htmlToCanvas(markEle); // 先壓縮和旋轉(zhuǎn)圖片 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); } }); }
上傳圖片,回顯圖片
<template> <div class="content-box"> <div class="container"> <div class="title">點(diǎn)擊上傳圖像(支持image/jpg,image/jpeg,image/png,image/gif格式圖片且大小不能超過10MB)</div> <div class="uploadImg"> <span class="el-icon-plus"></span> <input :accept="accept" type="file" class="upload_ipu" ref="fileLoad" @change="uploadImg" /> </div> <div class="imgList"> <img v-if="imgShow" :src="imgSrc" /> </div> <img v-if="imgShow" :src="fileUrl" /> <!-- 圖片上傳水印 --> <div id="markImg"> <div class="logo"> 圖片水?。? <img src="@/assets/logo.png" /> </div> <p>文字水?。簕{ loginName }}</p> </div> </div> </div> </template> <script> import { compressor, addWaterMarker } from "../utils/imageUtils.js"; import apis from "@/api"; const { commonSys: { commonUploadFile }, } = apis; export default { props: { accept: { type: String, default: "image/jpg,image/jpeg,image/png,image/gif", }, }, data() { return { imgShow: false, imgSrc: "", loginName: "fqniu", fileDate: new Date(), needWaterMark: true, fileUrl: "", }; }, // created() { // this.parseTime = parseTime // }, methods: { createUrl(file) { if (window.URL) { return window.URL.createObjectURL(file); } else if (window.webkitURL) { return window.webkitURL.createObjectURL(file); } else { return null; } }, async uploadImg() { // 這個(gè)是元素dom節(jié)點(diǎn) console.log(this.$refs.fileLoad); // 上傳文件fileList console.log(this.$refs.fileLoad.files); let file = this.$refs.fileLoad.files[0]; let size = file.size / 1024 / 1024; console.log(file, file.lastModifiedDate); if (!this.accept.includes(file.type.toLowerCase())) { this.$message.error("圖片格式不正確!"); return false; } if (size > 10) { this.$message.error("圖片大小不能超過10MB!"); return false; } // 壓縮圖片 // 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", "leftDown"); file.name = fileName; } this.imgSrc = this.createUrl(file); console.log(this.imgSrc); console.log(file); this.httpRequest(file); this.$message.success("上傳成功!"); }, httpRequest(fileObj) { // let fileObj = param.file; // 相當(dāng)于input里取得的files console.log(fileObj); let fd = new FormData(); // FormData 對(duì)象 fd.append("file", fileObj); // 文件對(duì)象 commonUploadFile("qms", fd).then((res) => { console.log(res.fileUrl); this.fileUrl = res.fileUrl; this.imgShow = true; }); }, }, }; </script> <style lang="scss" scoped> .container { margin: 50px; } .title { font-size: 16px; color: #73777b; } .uploadImg { margin-top: 20px; border: 1px dashed #d9d9d9; border-radius: 6px; cursor: pointer; position: relative; overflow: hidden; width: 180px; height: 180px; transition: all 0.2s; background: #fff; &:hover { border-color: #409eff; } span { font-size: 28px; color: #8c939d; width: 178px; height: 178px; line-height: 178px; text-align: center; } .upload_ipu { opacity: 0; width: 100%; height: 100%; position: absolute; cursor: pointer; top: 0; left: 0; z-index: 2; } img { width: 178px; height: 178px; position: absolute; border-radius: 6px; left: 0; top: 0; z-index: 1; } } .imgList { width: 550px; height: 400px; img { width: 100%; height: 100%; } } // 水印樣式 #markImg { position: absolute; left: -9999999px; text-align: left; padding: 10px 15px; .logo { font-weight: 600; font-size: 15px; color: #ffffff; display: flex; height: 21px; align-items: center; justify-content: flex-start; img { height: 21px; margin-right: 5px; } } p { margin-top: 6px; color: #ffffff; font-size: 12px; font-weight: 400; } } </style>
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
VUE搭建分布式醫(yī)療掛號(hào)系統(tǒng)后臺(tái)管理頁面示例步驟
這篇文章主要為大家介紹了分布式醫(yī)療掛號(hào)系統(tǒng)之搭建后臺(tái)管理系統(tǒng)頁面,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04vue.js實(shí)現(xiàn)條件渲染的實(shí)例代碼
這篇文章主要介紹了vue.js實(shí)現(xiàn)條件渲染的實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06vue3點(diǎn)擊出現(xiàn)彈窗后背景變暗且不可操作的實(shí)現(xiàn)代碼
這篇文章主要介紹了vue3點(diǎn)擊出現(xiàn)彈窗后背景變暗且不可操作的實(shí)現(xiàn)代碼,本文通過實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08vue雙向數(shù)據(jù)綁定原理分析、vue2和vue3原理的不同點(diǎn)
這篇文章主要介紹了vue雙向數(shù)據(jù)綁定原理分析、vue2和vue3原理的不同點(diǎn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12vue+element UI中如何給指定日期添加標(biāo)記
這篇文章主要介紹了vue+element UI中如何給指定日期添加標(biāo)記問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-02-02