vueプロジェクトでは、アップロードした画像に透かしを追加して参照できるようにするアップグレード版を実装しています。具体的な内容は次のとおりです。 カプセル化透かし方式 /** * 透かしを追加 * @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) { コンソールログ(エラーメッセージ) } }) }) } 透かしを使用してページ内の画像を圧縮する <テンプレート> <div> <el-アップロード アクション="" :headers="アップロードプロパティのヘッダー" リストタイプ="絵カード" :ファイルリストを表示="false" :http-request="fnアップロードリクエスト" :on-success="ハンドル成功" :before-upload="handleUpload" accept=".png,.jpg,.jpeg,.gif,.webp" > <div class="flex-center"> <スロット></スロット> </div> </el-アップロード> <!-- 画像アップロードの透かし --> <div id="markImg"> <div class="logo"> <img src="@/assets/img/icon-logo.png" /> テキストテキスト</div> <p> {{ parseTime(fileDate, '{y}-{m}-{d} {h}:{i}:{s}') }} 週 {{ parseTime(ファイル日付、'{a}') }} </p> <p>{{ 実行者 }}</p> </div> </div> </テンプレート> <スクリプト> 輸入 { アクセストークンを取得、 リフレッシュトークンを取得、 アクセストークンTTLを取得する } '@/utils/auth' から '@/utils/ossImage' から { uploadOSS } をインポートします '@/utils' から { parseTime、compressor、addWaterMarker } をインポートします。 エクスポートデフォルト{ 名前: 'インデックス', 小道具: { ウォーターマークが必要: タイプ: ブール値、 デフォルト: false }, 執行者: { タイプ: 文字列、 デフォルト: '' } }, データ() { 戻る { fileDate: 新しいDate() } }, 作成された() { this.parseTime = 解析時間 }, 計算: { ユーザーアカウントID() { this.$store.state.user.userAccountID を返します }, アップロードプロパティ() { 戻る { // アクション: `${process.env.VUE_APP_BASE_API}/api/image/upload`, ヘッダー: { // インターフェースにはトークンが必要な場合があります: "", 認証: getAccessToken() }, データ: {} } } }, メソッド: { // beforeUpload_u(ファイル、ファイルリスト){ // // console.log(ファイル、ファイルリスト); // var testmsg = file.name.substring(file.name.lastIndexOf('.') + 1) // const extension = testmsg === 'png' || testmsg === 'jpg' || testmsg === 'jpeg' || testmsg === 'gif' || testmsg === 'webp' // 定数 isLimit10M = ファイルサイズ / 1024 / 1024 < 10 // var bool = false; // if(拡張子 && isLimit10M){ // ブール値 = true; // } それ以外 { // ブール値 = false; // } // if(!拡張子) { // this.$message.error('画像形式のファイルをアップロードしてください!'); // ブール値を返します。 // } // if(!isLimit10M) { // this.$message.error('アップロードに失敗しました。10Mを超えることはできません!'); // ブール値を返します。 // } // ブール値を返します。 // }, // ハンドル成功(res) { // コンソールログ(res); // res.code == 0 の場合 { // this.$emit('imgData', res.item); // this.$message.success('画像のアップロードに成功しました!'); // } それ以外 { // this.$message.error('画像のアップロードに失敗しました!'); // } // }, // エラー処理(err){ // this.$message.error('画像のアップロードに失敗しました!'); // }, // アップロード画像判定 handleUpload(file, fileList) { var testmsg = file.name.substring(file.name.lastIndexOf('.') + 1) const拡張 = testmsg.toLowerCase() === 'png' || testmsg.toLowerCase() === 'jpg' || testmsg.toLowerCase() === 'jpeg' || testmsg.toLowerCase() === 'gif' || testmsg.toLowerCase() === 'webp' 定数isLimit10M = ファイルサイズ / 1024 / 1024 < 10 var ブール = false if (拡張子 && isLimit10M) { ブール値 = 真 } それ以外 { ブール値 = 偽 } if (!拡張子) { this.$message.error('画像形式のファイルをアップロードしてください!') ブール値を返す } 10M を超えると this.$message.error('アップロードに失敗しました。10Mを超えることはできません!') ブール値を返す } ブール値を返す }, // 画像をアップロード async fnUploadRequest(options) { 試す { let file = options.file // ファイルを取得する this.fileDate = file.lastModifiedDate // 画像を圧縮する if (file.size > 512 * 1024 && file.type.includes('image/')) { ファイル = コンプレッサー(ファイル)を待つ } // ウォーターマークを追加するif (this.needWaterMark) { const ファイル名 = ファイル名 ファイル = addWaterMarker(ファイル、'#markImg') を待機します file.name = ファイル名 } res = await uploadOSS(ファイル) とします。 // 返されるのは画像アドレスです this.$emit('imgData', res) this.$message.success('画像のアップロードに成功しました!') } キャッチ (e) { コンソール.log(e) this.$message.error('画像のアップロードに失敗しました。もう一度アップロードしてください') } }, //画像アップロード成功コールバック handleSuccess(res) { // コンソールログ(res); もし(res){ this.$emit('imgData', res) } } } } </スクリプト> <style lang="scss" スコープ> ::v-deep .el-アップロード、 ::v-deep .el-upload--picture-card { // 幅: 120px; 高さ: 24px; 高さ: 0; 境界線: なし; 行の高さ: 0; 表示: ブロック; 背景: #f5f6fb; } // ::v-deep .el-upload{ // 幅: 50px; // } .img-続き{ 幅: 50px; 高さ: 24px; 背景: #f5f6fb; .imgアイコン{ 色: #ccc; } .img-テキスト { フォントサイズ: 12px; 高さ: 24px; 色: #000; } } #マーク画像 { 位置: 絶対; 左: -9999999px; テキスト配置: 右; パディング: 10px 15px; .ロゴ { フォントの太さ: 600; フォントサイズ: 15px; 色: #ffffff; ディスプレイ: フレックス; 高さ: 21px; アイテムの位置を中央揃えにします。 コンテンツの端揃え: flex-end; 画像 { 高さ: 21px; 右マージン: 5px; } } p { 上マージン: 6px; 色: #ffffff; フォントサイズ: 12px; フォントの太さ: 400; } } </スタイル> 透かし方式の更新版 /** * 画像を圧縮して回転する * @param {blob} ファイル * @param {number} 品質圧縮率 * @param {number} 最大幅 * @returns {Promise} */ エクスポート関数コンプレッサー(ファイル、drew、maxWidth = 750、quality = 0.6) { 新しいPromiseを返します(resolve => { 新しいコンプレッサー(ファイル、{ 厳密: 偽、 最大幅、 品質、 描いた、 成功:解決、 エラー(err) { コンソールログ(エラーメッセージ) } }) }) } /** * 透かしを追加 * @param {blob} ファイル * @param {文字列} el * @returns {Promise} */ 非同期関数 addWaterMarker(file, el = '#brandMarkImg', direction = 'rightDown') をエクスポートします。 新しい Promise(async (resolve, reject) => { を返します。 試す { 定数最大幅 = 750 const img = blobToImg(ファイル) を待機します const imgWidth = img.naturalWidth > maxWidth ? maxWidth : img.naturalWidth // 透かし画像を生成する const markEle = document.querySelector(el) 定数スケール = imgWidth * 0.25 / markEle.clientWidth // 最初に透かしを拡大縮小してから画像に変換します markEle.style.transform = `scale(${scale})` const markImg = htmlToCanvas(markEle) を待機します // 最初に画像を圧縮して回転します file = await compressed(file, (context, canvas) => { if(方向 == 'rightDown'){ // 透かしの右下隅を塗りつぶします context.drawImage(markImg, canvas.width - markImg.width - 15 * scale, canvas.height - markImg.height - 15 * scale, markImg.width, markImg.height) } それ以外 { // 透かしの左下隅を塗りつぶします context.drawImage(markImg, 15 * scale, canvas.height - markImg.height - 15 * scale, markImg.width, markImg.height) } }, 最大幅) 解決(ファイル) } キャッチ(エラー){ 拒否(エラー) } }) } 関数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, {を待つ スケール: 2, allowTaint: false, //汚染を許可する useCORS: true, backgroundColor //'transparent' //背景色}) 解決(マーク画像) } キャッチ(エラー){ 拒否(エラー) } }) } 以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: Navicat が MySql サーバーにリモート接続できない問題の解決策
>>: Ubuntu 20.04 に cuda10.1 をインストールする手順 (グラフィック チュートリアル)
1. 概要Redis Cluster は、Redis ノードのグループ間での高可用性とシャーディング...
OBS studioかっこいいですが、 JavaScriptもっとかっこいいです。では、 JavaS...
目次Redux Toolkitが解決する問題何が含まれていますか? Redux Toolkit AP...
この記事では、Vueカウンターの簡単な実装コードを例として紹介します。具体的な内容は以下のとおりです...
これまでにも Docker 環境でいくつかのプロジェクトを実行したことはありますが、まだイメージをよ...
この記事の例では、vue3 が独自のページングコンポーネントをカプセル化する具体的なコードを参考まで...
プロフィールとは何ですか?特定の SQL のパフォーマンスを分析したい場合に使用できます。プロファイ...
B/S システム インターフェースを構築する場合、メイン ページ index.html 内に他のペー...
この記事では、例を使用して、MySQL 共同インデックスの機能と使用方法を説明します。ご参考までに、...
効果: GROUP_CONCAT関数は、フィールド値を文字列に連結することができます。デフォルトの区...
始める前にクラウドサーバーを持っています。私のはTencent Cloud Server (Cent...
/****************** * 高度な文字デバイス ドライバー ***********...
エラー発生: MySQL 5.7 から SQL にデータベースをエクスポートし、それを MySQL ...
MySQL公式サイトのzipファイルのダウンロードリンク https://dev.mysql.co...
1. 仮想マシン(物理マシン)をインストールする仮想マシンまたは物理マシンにインストールできます。 ...