Vue はアップロードされた画像に透かしを追加する機能を実装します

Vue はアップロードされた画像に透かしを追加する機能を実装します

この記事では、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 を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • Vue で画像と画像の透かしを隠しテキスト情報とともに使用する方法
  • Vueはページに透かし効果を追加する機能を実装します
  • Vue は PDF.js を統合して PDF プレビューを実装し、透かしを追加する手順を実行します。
  • Vueはページ透かし機能を実装
  • Vueを使用して写真をアップロードする3つの方法
  • モバイル端末上のVue+Vantのアップローダーは、画像のアップロード、圧縮、回転の機能を実現します。
  • Vue+elementUI はフォームと画像のアップロードおよび検証機能の例を実装します
  • vue+elementUIは画像アップロード機能を実現します
  • VUEをベースに画像を選択してアップロードし、ページに表示します(画像は削除可能です)
  • Vue はアップロードした画像に透かしを追加できるようになりました (アップグレード版)

<<:  4 つの主要な SQL ランキング関数 ROW_NUMBER、RANK、DENSE_RANK、NTILE の使用方法の紹介

>>:  Linux での中国語入力方法の問題を素早く解決する

推薦する

Tomcatがセッションを管理する方法の例

ConcurrentHashMapを学習しましたが、どのように適用すればよいかわかりませんか? To...

MySql 範囲内の検索時にインデックスが有効にならない理由の分析

1 問題の説明この記事では、確立された複合インデックスをソートし、レコード内の非インデックス フィー...

MySQL ユーザーと権限、およびルートパスワードをクラックする方法の例

MySQL ユーザーと権限MySQL には、MySQL と呼ばれるシステムに付属するデータベースがあ...

40 CSS/JSスタイルと機能的な技術処理

1-ドロップダウン選択ボックスのスタイル設定 - ドロップダウン リストを変更します。 2- <...

MySQL でデータベースを作成した後、ユーザー 'root'@'%' によるデータベース 'xxx' へのアクセスが拒否される問題を解決する

序文最近、仕事で問題が発生しました。データベースを作成した後、データベースに接続するときにエラーが発...

NodeJs の高メモリ使用量のトラブルシューティング実戦記録

序文これは、オンライン コンテナーの拡張によって発生した調査です。最終的には、実際の OOM が原因...

49 個の JavaScript のヒントとコツ

目次1. js整数の演算2. ネイティブアラートを書き換えてポップアップボックスの数を記録する3. ...

CSSでサウンドを再生するいくつかのテクニック

CSS は、スタイル、レイアウト、プレゼンテーションの領域です。色彩、サイズ、アニメーションが溢れて...

Centos7 に mysql と mysqlclient をインストールする際に遭遇する落とし穴の概要

1. MySQL Yumリポジトリを追加するMySQL公式サイト>ダウンロード>MySQ...

jQueryの競合問題を解決する方法

フロントエンド開発において、$ は jQuery の関数です。$ のパラメータが異なると、実装される...

nginx でのリクエストのカウント追跡の簡単な分析

まずは適用方法を説明します。nginxモジュールにはjtxyとjtcmdの2つがあります。 http...

Centos8 で yum を使用して mongodb 4.2 をインストールする方法

1. リポジトリファイルを作成するmongodb の公式インストール ドキュメントを参照し、次のスク...

DockerでRedisを使用するための詳細な手順

1. はじめにこの記事では、Docker を使用して Redis を探索する方法を説明します。 Do...

Nginxはhttpリクエスト実装プロセス分析を処理する

Nginxはまず、設定ファイル内のどのserver{}ブロックを処理に使用するかを決定します。次のs...