この記事では、Vueでアップロードされた画像に透かしを追加する具体的な実装コードを参考までに共有します。具体的な内容は次のとおりです。 1. カプセル化と透かしの方法 /** * 透かしを追加 * @param {blob} ファイル * @param {文字列} el * @returns {Promise} */ 非同期関数 addWaterMarker(file, el = '#markImg') をエクスポートします。 新しい Promise(async (resolve, reject) => { を返します。 試す { // 最初に画像を圧縮して回転します。file = await compressed(file) // ファイル blob を画像に変換する let img = await blobToImg(file) // キャンバスを作成する let canvas = document.createElement('canvas') キャンバスの幅 = img.naturalWidth キャンバスの高さ = img.naturalHeight ctx = canvas.getContext('2d') とします。 // アップロードされた画像を塗りつぶす ctx.drawImage(img, 0, 0, canvas.width, canvas.height) // 透かし画像を生成する const markEle = document.querySelector(el) const markWidth = markEle.clientWidth 定数スケール = キャンバス.幅 * 0.25 / マーク幅 // 最初に透かしを拡大縮小してから画像に変換します markEle.style.transform = `scale(${scale})` const markImg = htmlToCanvas(markEle) を待機します // 透かしを塗りつぶす ctx.drawImage(markImg, canvas.width - markImg.width - 15 * scale, canvas.height - markImg.height - 15 * scale, markImg.width, markImg.height) //キャンバスをblobに変換する canvas.toBlob(blob => 解決(blob)) } キャッチ(エラー){ 拒否(エラー) } }) } 関数blobToImg(blob) { 新しい Promise を返します ((resolve, reject) => { リーダーを新しいFileReader()にします リーダー.addEventListener('load', () => { img = new Image() とします。 img.src = リーダー結果 img.addEventListener('load', () => 解決(img)) }) リーダー.readAsDataURL(blob) }) } エクスポート関数 htmlToCanvas(el, backgroundColor = 'rgba(0,0,0,.1)') { 新しい Promise(async (resolve, reject) => { を返します。 試す { const markImg = html2canvas(el, {を待つ scale: 2, //デフォルト値window.devicePixelRatioはここでは使用されません。モバイル側と一致させる必要がありますallowTaint: false, //汚染を許可しますuseCORS: true, backgroundColor //'transparent' //背景色}) 解決(マーク画像) } キャッチ(エラー){ 拒否(エラー) } }) } /** * 画像を圧縮して回転する * @param {blob} ファイル * @param {number} 品質圧縮率 * @param {number} 最大幅 * @returns {Promise} */ エクスポート関数コンプレッサー(ファイル、品質 = 0.6、最大幅 = 750) { 新しいPromiseを返します(resolve => { 新しいコンプレッサー(ファイル、{ 最大幅、 品質、 成功:解決、 エラー(err) { コンソールログ(エラーメッセージ) } }) }) } 2. プロジェクトでの使用 <!-- 画像のアップロード --> <div class="flex mt20" v-if="item.questionType === 4"> <バンアップローダー v-model="item.imgアップロード" 複数="true" 遅延読み込み :deletable="!isDisabled" :disabled="無効" @delete="handleDeleteImg({ ...引数, 項目 })" :before-read="handleBeforeImgUpload" :after-read="handleAfterImgUpload" @click.native="現在のアイテム = アイテム" /> </div> <スクリプト> 輸入 { タスクの詳細を取得、 ユーザー実行、 送信フロー、 拒否フロー、 } '@/api/myTask' から; '@/utils/oss' から { uploadOSS } をインポートします。 '@/utils' から parseTime、addWaterMarker をインポートします。 'vant' から ImagePreview をインポートします。 'compressorjs' から Compressor をインポートします。 const fileExtensions = ['xlsx', 'xls', 'docx', 'doc', 'pdf']; const quality = 0.2; //画像圧縮品質 export default { メソッド: { // アップロードする前に async handleBeforeImgUpload(img, detail) { もし(!img){ 戻る } 新しい Promise(async (resolve, reject) => { を返します。 Array.isArray(画像)の場合{ 画像の長さが5より大きい場合 this.$toast('一度に最大 5 枚の写真をアップロードできます。数回に分けてアップロードしてください。') 拒否する() } ブロブを [] にする for (const ファイル img) { // 512kより大きい画像は最初に圧縮されます if (file.size > 512 * 1024 && file.type.includes('image/')) { ファイル = this.compressor(ファイル) を待機します } // 透かしを追加 let blob = await addWaterMarker(file) blob.name = ファイル名 blobs.push(blob) } 解決(ブロブ) } それ以外 { // 512kより大きい画像は最初に圧縮する必要があります if (img.size > 512 * 1024 && img.type.includes('image/')) { img = this.compressor(img) を待機します } const blob = await addWaterMarker(img) blob.name = 画像名 解決(ブロブ) } }) }, //アップロード後 async handleAfterImgUpload(img, detail) { 試す { $読み込み中.表示() Array.isArray(画像)の場合{ img.forEach(async ({ファイル},インデックス) => { if (!file.name || !file.type.includes('image/')) { this.currentItem.imgUpload.splice(detail.index + index, 1) this.$toast('アップロードに失敗しました。写真のみアップロードできます!') // アップロード完了 if (index === img.length - 1) { $loading.hide() } return // forEach の return は continue と同等です } ファイルサイズが 1024 * 1024 * 10 より大きい場合 this.currentItem.imgUpload.splice(detail.index + index, 1) this.$toast('ファイルが大きすぎます。1 つのファイルは 10 MB を超えることはできません。') // アップロード完了 if (index === img.length - 1) { $loading.hide() } 戻る } 試す { const { ファイル名, url } = アップロードOSS(ファイル)を待つ this.currentItem.answer.push({ URL、 }) } キャッチ(エラー){ this.currentItem.imgUpload.splice(detail.index + index, 1) this.$toast('アップロードに失敗しました。しばらくしてからもう一度お試しください!') コンソール.エラー(エラー) } // アップロード完了 if (index === img.length - 1) { $loading.hide() } }) } それ以外 { if (!img.file.type.includes('image')) { this.currentItem.imgUpload.splice(詳細インデックス、1) $loading.hide() this.$toast('アップロードに失敗しました。アップロードできるのは写真のみです!') 戻る } (img.file.size >= 1024 * 1024 * 10) の場合 { this.currentItem.imgUpload.splice(詳細インデックス、1) $loading.hide() this.$toast('ファイルが大きすぎるため、10MB を超えることはできません。') 戻る } // 512kより大きい場合は、まず圧縮します。let file = img.file const { ファイル名, url } = アップロードOSS(ファイル)を待つ this.currentItem.answer.push({ URL、 }) $loading.hide() } } キャッチ(エラー){ this.currentItem.imgUpload.splice(詳細インデックス、1) $loading.hide() this.$toast('アップロードに失敗しました。しばらくしてからもう一度お試しください!') コンソール.エラー(エラー) } } } 指導してくださったロング兄弟に感謝します。 3. 効果は以下のとおりです 以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: 4 つの主要な SQL ランキング関数 ROW_NUMBER、RANK、DENSE_RANK、NTILE の使用方法の紹介
>>: Linux での中国語入力方法の問題を素早く解決する
一般的な開発ニーズとして、要素の一部を必要になるまで折りたたんでおきたいことが挙げられます。 Boo...
目次1. インストールとインポート2. 手ぶれ補正機能を定義する3. チャートコードを描くinit ...
Dockerデスクトップをインストールするダウンロード先: Docker Desktop for M...
JSON は、言語に依存しないテキスト形式を使用する軽量のデータ交換形式で、XML に似ていますが、...
序文スタンドアロン ロックであっても分散ロックであっても、共有データに基づいて現在の操作の動作を判断...
1. インストール1. ダウンロードMySQLをダウンロードするには、MySQL公式サイトhttp:...
CSS でテキストを中央揃えにするプロパティは非常に簡単に実現できます。text-align:cen...
目次ウェブAPI DOM DOMツリーDOM要素取得方法ドキュメントオブジェクトのプロパティイベント...
iノードとは何ですか? inode を理解するには、まずファイル ストレージから始める必要があります...
1.1 nginxインストールパッケージとインストールスクリプトをクライアントにコピーし、スクリプト...
まとめHTML: 要素と v-cloak CSS: [v-cloak]{表示: なし}プロセスページ...
目次序文for文の無限ループを修正while文の無限ループを修正要約する序文Js デッド ループはど...
1. インストール環境コンピュータモデル: Lenovo Y471a (i5) ノートパソコンシステ...
1. VMware vSphere の概要VMware vSphere は、業界をリードする最も信...
目次1.1 前提条件としてのJava環境1.2 Zookeeperのインストールと設定1.3 Kaf...