【vue】vue + vant實現上傳圖片添加水印

目錄

方法1:使用HTML2canvas

說明:

優點

缺點

依賴安裝

方法2:使用canvas結合vant中組件

增加水印方法

在vue組件中使用

要點


方法1:使用HTML2canvas

使用html2canvas來處理水印的生成,需要就給水印元素轉換為canvas圖像并疊加到上傳的圖片。

<template><div><van-uploader :after-read="afterRead" /><!-- 水印元素 --><div id="watermark" style="display: none;"><div style="font-size: 20px; color: rgba(0, 0, 0, 0.3); transform: rotate(-45deg); position: absolute; top: 50%; left: 50%; transform-origin: center;">水印文本</div><!-- 如果需要圖片水印,可以在這里添加圖片元素 --><img src="path/to/watermark.png" style="position: absolute; bottom: 10px; right: 10px; width: 100px; height: 100px; opacity: 0.3;" /></div></div>
</template><script>
import { ref } from 'vue';
import html2canvas from 'html2canvas';export default {setup() {const afterRead = async (file) => {// 創建 canvas 元素const canvas = document.createElement('canvas');const ctx = canvas.getContext('2d');// 設置 canvas 尺寸為圖片尺寸const img = await new Promise((resolve) => {const img = new Image();img.src = file.content;img.onload = () => resolve(img);});canvas.width = img.width;canvas.height = img.height;// 繪制原始圖片ctx.drawImage(img, 0, 0);// 獲取水印元素并轉換為 canvasconst watermarkElement = document.getElementById('watermark');const watermarkCanvas = await html2canvas(watermarkElement, {logging: false,scale: window.devicePixelRatio, // 高清屏支持useCORS: true, // 啟用跨域});// 將水印 canvas 繪制到主 canvas 上ctx.drawImage(watermarkCanvas, 0, 0, canvas.width, canvas.height);// 將 canvas 轉換為 Blob 并替換文件內容canvas.toBlob((blob) => {file.file = blob;file.content = URL.createObjectURL(blob);}, 'image/png');};return {afterRead,};},
};
</script>

    說明:

    html2canvas 配置

    logging: false:禁用日志輸出。

    scale: window.devicePixelRatio:支持高清屏。

    useCORS: true:啟用跨域,確保圖片資源可以被正確加載。

    繪制水印

    使用 html2canvas 將水印元素轉換為 canvas 圖像。

    將生成的水印 canvas 圖像繪制到主 canvas 上。

    生成最終圖片

    將主 canvas 轉換為 Blob,并替換上傳的文件內容。

    優點
    1. 靈活性高:可以將任何 HTML 元素轉換為 canvas 圖像,這意味著你可以使用 HTML 和 CSS 創建非常復雜的水印效果,比如帶有圖標、多行文本、不同字體和顏色等。

    2. 可視化設計:可以直接在頁面上設計水印的樣式,所見即所得,不需要通過代碼去想象最終效果。

    3. 兼容性較好html2canvas 會盡可能地將頁面元素渲染成與瀏覽器中顯示一致的圖像,減少了因手動繪制帶來的兼容性問題。

    缺點
    1. 依賴外部庫:需要引入 html2canvas 庫,增加了項目的依賴和體積。

    2. 性能問題:將 HTML 元素轉換為 canvas 圖像的過程可能會有一定的性能開銷,尤其是在水印元素復雜或者頁面元素較多的情況下。

    3. 配置復雜:可能需要調整 html2canvas 的各種配置選項,以確保生成的圖像符合預期,比如設置背景色、處理透明度等。

    依賴安裝
    cnpm install compressorjs html2canvas

    方法2:使用canvas結合vant中組件

    使用純canvas操作直接繪制水印文本

    vant的van-uploader組件提供了after-read事件,在其中調用水印處理函數

    增加水印方法
    /*** 添加水印* @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 轉換成 blobcanvas.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,allowTaint: false,useCORS: true,backgroundColor,});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);},});});
    }
    在vue組件中使用
    <template><div><van-uploaderv-model="fileList"multiple:after-read="afterRead":before-read="beforeRead"/><!-- 水印內容 --><div id="markImg" style="display: none;"><div style="font-size: 14px; color: rgba(255, 255, 255, 0.3);">水印文字</div></div></div>
    </template><script>
    import { addWaterMarker, compressor } from '@/utils/watermark';
    import Compressor from 'compressorjs';export default {data() {return {fileList: [], // vant 中圖片上傳的雙向綁定};},methods: {// 上傳前處理async beforeRead(file) {return new Promise(async (resolve, reject) => {if (Array.isArray(file)) {if (file.length > 5) {this.$toast('一次最多上傳5張,請分批次上傳!');reject();return;}let blobs = [];for (const f of file) {// 大于 512k 的圖片則先壓縮if (f.size > 512 * 1024 && f.type.includes('image/')) {f = await this.compressor(f);}// 添加水印let blob = await addWaterMarker(f);blob.name = f.name;blobs.push(blob);}resolve(blobs);} else {// 大于 512k 的圖片則先壓縮if (file.size > 512 * 1024 && file.type.includes('image/')) {file = await this.compressor(file);}const blob = await addWaterMarker(file);blob.name = file.name;resolve(blob);}});},// 上傳后處理async afterRead(file) {// 處理上傳邏輯console.log('上傳成功', file);},// 壓縮圖片async compressor(file) {return new Promise((resolve) => {new Compressor(file, {quality: 0.6,success: resolve,error(err) {console.log(err.message);},});});},},
    };
    </script>
    要點

    addWaterMarker:添加水印的核心方法,負責將水印內容繪制到圖片上。

    beforeRead:在圖片上傳前處理,包括壓縮和添加水印。

    afterRead:圖片上傳后的處理邏輯。

    使用了 html2canvas 將水印內容轉換為圖片。

    使用了 compressorjs 對圖片進行壓縮。

    碼字不易,各位大佬點點贊唄

    本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
    如若轉載,請注明出處:http://www.pswp.cn/diannao/75692.shtml
    繁體地址,請注明出處:http://hk.pswp.cn/diannao/75692.shtml
    英文地址,請注明出處:http://en.pswp.cn/diannao/75692.shtml

    如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

    相關文章

    【深度破解】爬蟲反反爬核心技術實踐:驗證碼識別與指紋偽裝

    一、反爬技術體系全景圖 現代Web應用的常見反爬手段&#xff1a; mermaid&#xff1a; graph TDA[反爬體系] --> B[行為特征檢測]A --> C[驗證碼體系]A --> D[指紋追蹤]B --> B1[請求頻率]B --> B2[鼠標軌跡]B --> B3[頁面停留時間]C --> C1[圖形驗證碼…

    deepseek(2)——deepseek 關鍵技術

    1 Multi-Head Latent Attention (MLA) MLA的核心在于通過低秩聯合壓縮來減少注意力鍵&#xff08;keys&#xff09;和值&#xff08;values&#xff09;在推理過程中的緩存&#xff0c;從而提高推理效率&#xff1a; c t K V W D K V h t c_t^{KV} W^{DKV}h_t ctKV?WDKVht?…

    OpenGL繪制文本

    一&#xff1a;QPainter繪制 在 OpenGL 渲染的窗口中&#xff08;如 QOpenGLWidget&#xff09;&#xff0c;通過 QPainter 直接繪制文本。Qt 會自動將 2D 內容&#xff08;文本、圖形&#xff09;與 OpenGL 內容合成。在paintGL()里面繪制&#xff0c;如果有其他紋理&#xf…

    從零構建大語言模型全棧開發指南:第二部分:模型架構設計與實現-2.1.3前饋網絡(FFN)與激活函數(GELU)優化

    ?? 點擊關注不迷路 ?? 點擊關注不迷路 ?? 點擊關注不迷路 文章大綱 2.1.3 前饋網絡(FFN)與激活函數(GELU)優化1. 前饋網絡(FFN)的架構設計與數學原理1.1 FFN在Transformer中的核心作用2. GELU激活函數的數學特性與優化2.1 GELU的數學形式與近似計算3. 逐行代碼實現…

    React 中的錯誤邊界(Error Boundaries),如何使用它們捕獲組件錯誤

    大白話React 中的錯誤邊界&#xff08;Error Boundaries&#xff09;&#xff0c;如何使用它們捕獲組件錯誤 在 React 里&#xff0c;錯誤邊界就像是一個“小衛士”&#xff0c;專門負責在組件出現錯誤時挺身而出&#xff0c;避免整個應用因為一個小錯誤就崩潰掉。接下來我會詳…

    數據庫DBA認證,選哪個認證合適?

    從 Oracle、MySQL 到 云數據庫&#xff0c;結合市場認可度、考試難度及職業回報&#xff0c;為你精選高性價比認證。 一、企業級數據庫認證&#xff08;傳統場景&#xff09; 1. Oracle認證 認證等級考試代碼核心內容費用適合人群OCA1Z0-082SQL基礎、數據庫安裝與配置$245零基…

    力扣刷題-熱題100題-第24題(c++、python)

    234. 回文鏈表 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/palindrome-linked-list/description/?envTypestudy-plan-v2&envIdtop-100-liked 常規法 數組是連續的存儲空間&#xff0c;可以根據索引到達任意位置&#xff0c;鏈表只能一個個的順…

    調用通義千問實現語音合成并將合成的音頻通過揚聲器播放

    1. 作者介紹 郭建東&#xff0c;男&#xff0c;西安工程大學電子信息學院&#xff0c;2024級研究生 研究方向&#xff1a;機器視覺與人工智能 電子郵件&#xff1a;1229963266qq.com 高金年&#xff0c;男&#xff0c;西安工程大學電子信息學院&#xff0c;2024級研究生&…

    Ubuntu軟件包離線下載安裝

    1、下載軟件包tcpd&#xff0c;并在/var/cache/apt/archives目錄中查看。 rooteducoder:~# apt-get install -d tcpd Reading package lists... Done Building dependency tree Reading state information... Done The following NEW packages will be installed:tcpd …

    您的數據是如何出現在暗網上的?

    暗網是互聯網上的一個隱秘角落&#xff0c;人們可以在那里保持匿名。暗網經常與深網混淆&#xff0c;但它們并不完全相同。 深網是指網絡上所有未被搜索引擎索引的內容。這包括電子郵件帳戶、私人數據庫和付費服務等。這并不違法&#xff0c;只是無法通過簡單的 Google 搜索找…

    原型模式及其應用

    引言 原型模式&#xff08;Prototype Pattern&#xff09;是一種創建型設計模式&#xff0c;它允許通過復制現有對象來創建新對象&#xff0c;而無需通過構造函數來創建。這種模式通過克隆現有對象來創建新對象&#xff0c;從而避免了復雜的初始化過程。本文將探討原型模式的好…

    thinkphp漏洞再現

    Thinkphp5x遠程命令執行及getshell 1、開環境 2、使用工具攻擊 開啟工具 輸入地址&#xff0c;點擊漏洞檢測 存在漏洞之后&#xff0c;選擇漏洞&#xff0c;執行命令 3、也可以執行遠程命令 執行命令 ?sindex/think\app/invokefunction&functioncall_user_func_array&…

    Day16 -實例:Web利用郵箱被動繞過CDN拿真實ip

    本想測試一下全局ping&#xff0c;剛好注冊的時候收到了郵件&#xff0c;剛好去做一下復現。 原理&#xff1a;主動讓對方站點給我們發郵件&#xff08;注冊、修改密碼、訂閱推送等&#xff09;我們查看郵件原文&#xff0c;原文里存在真實的郵件站點ip 特點&#xff1a;郵件…

    vue3 數據監聽(watch、watchEffect)

    1、watch 1.1基本使用 作用&#xff1a;數據監聽 語法&#xff1a; watch(監聽的數據, (改變后的數據, 改變前的數據) > { console.log(newVal, oldVal); }) 注意點&#xff1a;watch寫法上支持一個或者多個監聽源&#xff0c;這些監聽源必須只能是getter/effect函數…

    網盤解析工具更新,解決了一些bug

    解析工具v1.2.1版本更新&#xff0c;本次是小版本更新&#xff0c;修復了一些bug。 之前小伙伴反應的網盤進入文件后不能返回上一級&#xff0c;現在這個bug修復了&#xff0c;已經可以點擊了。 點擊資源后會回到資源那一級目錄&#xff0c;操作上是方便了不少。 增加了檢查自…

    推薦1款簡潔、小巧的實用收音機軟件,支持手機和電腦

    聊一聊 沒想到現在還有人喜歡聽廣播。 我一直以為聽廣播必須要用那種小廣播機才可以。 原來手機或電腦上也是可以的。 今天給大家分享一款可以在電腦和手機上聽廣播的軟件。 軟件介紹 龍卷風收音機 電臺廣播收音機分電腦和手機兩個版本。 電腦端無需安裝&#xff0c;下載…

    六十天前端強化訓練之第三十一天之Webpack 基礎配置 大師級講解(接下來幾天給大家講講工具鏈與工程化)

    歡迎來到編程星辰海的博客講解 看完可以給一個免費的三連嗎&#xff0c;謝謝大佬&#xff01; 目錄 一、Webpack 核心概念解析 二、實戰&#xff1a;多資源打包配置&#xff08;含完整代碼&#xff09; 三、配置深度解析&#xff08;重點部分說明&#xff09; 四、效果演示…

    機器學習——Bagging、隨機森林

    相比于Boosting的集成學習框架&#xff0c;Bagging(Bootstrap Sampling&#xff0c;自助聚集法&#xff0c;又稱為自助采樣)作為一種自助聚集且并行化的集成學習方法&#xff0c;其通過組合多個基學習器的預測結果來提高模型的穩定性和泛化能力。其中隨機森林是Bagging學習框架…

    【藍橋杯】每日練習 Day13

    前言 今天做了不少題&#xff0c;但是感覺都太水了&#xff0c;深思熟慮之下主播決定拿出兩道相對不那么水的題來說一下&#xff08;其實還是很水&#xff09;。 兩道問題&#xff0c;一道是日期問題&#xff08;模擬&#xff09;&#xff0c;一道是區間合并問題。 日期差值 …

    HTML輸出流

    HTML 輸出流 JavaScript 中**「直接寫入 HTML 輸出流」**的核心是通過 document.write() 方法向瀏覽器渲染過程中的數據流動態插入內容。以下是詳細解釋&#xff1a; 一、HTML 輸出流的概念 1. 動態渲染過程 HTML 文檔的加載是自上而下逐行解析的。當瀏覽器遇到 <script&…