Springboot+Vue-Cropperでアバターの切り取りとアップロードの効果を実現

Springboot+Vue-Cropperでアバターの切り取りとアップロードの効果を実現

アバターをアップロードするにはVue-Cropperコンポーネントを使用します。参考までに具体的な内容は以下のとおりです

エフェクト表示

まずは効果を見てみましょう。効果があなたのニーズを満たさない場合は、それを読み取るのに時間を無駄にする必要はありません。

画像をクリックすると

次に、「画像をアップロード」をクリックしてアップロードを完了します。具体的な効果とページレイアウトは次のようになります。

フロントエンドコード

使用する前に、vue-cropper の公式ドキュメントを詳しく読むことをお勧めします。詳細に紹介されており、必要に応じて変更できます: リンク

もう1つ: element-uiコンポーネントライブラリはプロジェクト全体で使用されます。使用する前にelement-uiをインポートしてください。

解説のためにコードにコメントを追加します。結局、理由を知るには起源を知らなければなりません。

<テンプレート>
  <div style="height: 800px;">
    <el-tabs v-model="activeName" @tab-click="handleClick" class="tabs">
      <el-tab-pane label="個人情報" name="first">
      </el-tab-pane>
      <el-tab-pane label="アバターを変更" name="second">
        <div class="アバター_ヘッダー">
          <span>現在のアバター</span>
        </div>
        <div class="アバター_current">
          <img :src="現在の画像">
        </div>
        <div class="アバター_select">
          <!-- 元の <input type="file"> タグがあまりにも醜いため、ここでこれを行います。どれほど醜いかは、自分で試して確かめてください。そのため、ボタンを使用してトリガー入力を制御し、ファイルを選択します -->
          <input type="file" ref="uploads" id="uploads" accept="image/png, image/jpeg, image/gif, image/jpg" hidden @change="setImage($event)">
          <el-button type="primary" @click="selectAvatar">画像を選択</el-button>

          <el-button type="success" style="margin-left:100px;" @click="uploadImg('blob')">写真をアップロード</el-button>
        </div>

        <div class="cropper_box">
        <div class="アバタークロッパー">
          <vue-クロッパー
            ref="クロッパー"
            :img="オプション.img"
            :outputSize="オプション.outputSize"
            :outputType="オプション.outputType"
            :info="オプション情報"
            :canScale="オプション.canScale"
            :autoCrop="オプション.autoCrop"
            :autoCropWidth="option.autoCropWidth"
            :autoCropHeight="option.autoCropHeight"
            :fixed="オプション.fixed"
            :fixedNumber="オプション.fixedNumber"
            :full="オプション.full"
            :fixedBox="オプション.fixedBox"
            :canMove="オプション.canMove"
            :canMoveBox="オプション.canMoveBox"
            :original="オプション.original"
            :centerBox="オプション.centerBox"
            :height="オプションの高さ"
            :infoTrue="オプション.infoTrue"
            :maxImgSize="オプション.maxImgSize"
            :enlarge="オプション.enlarge"
            :mode="オプションモード"
            @realTime="実時間"
            @imgLoad="画像読み込み">
          </vue-cropper>
        </div>

        <div class="show_preview" :style="{'width': previews.w + 'px', 'height': previews.h + 'px', 'overflow': 'hidden',
          'マージン': '5px'}">
          <div :style="previews.div">
            <img :src="option.img" :style="previews.img">
          </div>
        </div>
        </div>
      </el-tab-pane>

      <el-tab-pane label="パスワードの変更" name="third">

      </el-tab-pane>
    </el-tabs>
  </div>
</テンプレート>

<スクリプト>
'qs' から qs をインポートします
'vue-cropper' から { VueCropper } をインポートします

エクスポートデフォルト{
  データ() {
    戻る {
      アクティブ名:'second',
      currentimg:this.$store.getters.getAvatar, //ここで管理プレビュー用にユーザー情報をVuexに保存します:{},
      オプション:{
        img:'', //切り抜いた画像のアドレス,
        outputSize:1, // 切り取られた画像の品質はオプションです (0,1,-1)
        outputType:'jpeg', // 切り抜かれた画像のフォーマット info:true, // 画像サイズ情報 canScale:true, // ホイールズームを許可するかどうか autoCrop:true, // デフォルトでスクリーンショットフレームを生成するかどうか autoCropWidth:240,
        autoCropHeight:240, // デフォルトのスクリーンショットフレームサイズ fixed:true, // スクリーンショットフレームの幅と高さの固定比率を有効にするかどうか fixedNumber:[1,1], // スクリーンショットフレームのアスペクト比、
        full:false, // 画像を歪みなく元の比率でトリミングします fixedBox:true, // スクリーンショット ボックスのサイズを固定します。変更は許可されません canMove:false, // アップロードした画像を移動できますか?
        canMoveBox:true, //スクリーンショットボックスをドラッグできるかどうか original:false, //アップロードされた画像は元の比率に従ってレンダリングされる centerBox:false, //スクリーンショットボックスは画像に制限されるか height:true, //デバイスのDPRに従って比例画像を出力するかどうか infoTrue:false, //trueは実際の出力画像の幅と高さを表示し、falseはスクリーンショットボックスの幅と高さを表示するか、
        maxImgSize:3000, //画像の最大幅と高さを制限します。enlarge:1, //画像出力比率はスクリーンショットのフレームに応じて倍数になります。mode:'400px 300px' //画像のレンダリング方法}
    }
  },
  メソッド: {
    // タブ切り替え呼び出しメソッド、重要ではありません!不要なコードを削除しました handleClick(){
    },

    //メソッドselectAvatar()を呼び出して画像を選択する{
      this.$refs.uploads.click();
    },
    // 画像を選択するための実際のメソッド。とりあえずこのように名前を付けましょう setImage(e){
      ファイルをe.target.files[0]とします。
      if (!/\.(jpg|jpeg|png|JPG|PNG)$/.test(e.target.value)) {
        // this.$message.info("画像タイプが正しくありません");
        console.log("画像タイプが正しくありません");
        false を返します。
      }
      //blob に変換します。blob を使用する目的は、アップロードされた画像をページに表示することです。let reader = new FileReader();
      // ファイルが正常に読み込まれた後、onload メソッドがトリガーされます。 reader.onload = (e) => {
        データを入力します。
        // ページに表示するには、URL 形式に変換します if (typeof e.target.result === 'object') {
          データ = window.URL.createObjectURL(新しいBlob([e.target.result]))
        }それ以外{
          データ = e.target.result
        }
        this.option.img = データ
        //base64に変換
      }
      reader.readAsDataURL(ファイル)
    },

    リアルタイム(データ){
      this.previews = データ;
    },
    // 初期化関数 imgLoad(msg){
      console.log("ツール初期化関数 ====="+msg);
    },

    // アバターをアップロードするためのメソッドの呼び出し uploadImg(type){
      _this = this とします。
      if(type === 'blob'){
        //スクリーンショットのBLOBデータ型を取得します。this.$refs.cropper.getCropBlob(async (data) => {
          formData を新しい FormData() にします。
          // データをバックエンドに送信します。独自のバックエンド ロジックに従って処理してください。ユーザー名を Vuex に保存し、直接名前を付けることができます。formData.append("username", this.$store.getters.getUsername);
          formData.append('file',data,this.$store.getters.getUsername+".jpg");
          this.axios.post('/updateavatar',formData).then(function(response){
            console.log(応答);
            応答データコード == 200 の場合
              console.log(応答);
              _this.currentimg = レスポンスデータ.データ;
              _this.$store.commit('setAvatar',response.data.data); //新しいアバターをVuexに保存します
              _this.$router.go(0); //ウェブページを更新する}
          })
        })
      }

    }
  },

  コンポーネント:{VueCropper}
};

</スクリプト>

<スタイルスコープ>
.タブ作成{
  位置: 絶対;
  右: 80px;
  上: 115px;
  上マージン: 5px;
  zインデックス: 999;
}

.アバターヘッダー{
  幅: 100%;
  高さ: 50px;
  フォントサイズ: 14;
  行の高さ: 50px;
  フォントの太さ: 550;
  左パディング: 20px;
  テキスト配置: 左;
}

.アバター_current{
  幅: 100%;
  高さ: 260px;
  テキスト配置: 左;
}
.アバター_現在の画像{
  幅: 240ピクセル;
  高さ: 240px;
  左マージン: 20px;

}
.アバター選択{
  テキスト配置: 左;
}

.クロッパーボックス{
  テキスト配置: 左;
  位置: 相対的;
}
.アバタークロッパー{
  上マージン: 40px;
  高さ: 350ピクセル;
  幅: 450ピクセル;
  表示: インラインブロック;
}

.show_preview{
  表示: インラインブロック;
  位置: 絶対;
  上:30px;
  左: 500ピクセル;
}


</スタイル>

バックエンドコード

ここではまずバックエンド処理ロジックについて説明します。

1. アバターを取得すると、その画像はクラウド サーバーに保存されます。ここでは、ドライブ D に独自の静的ファイル ディレクトリを設定します (static_root を参照)。
2. 次に、クラウド サーバー上の画像の URL をバックエンドの MySQL データベースに保存します。
3. 画像の URL を含んだアップロード成功メッセージをフロントエンドに返します。これにより、URL を通じて画像にアクセスし、フロントエンドに表示できるようになります。

コントローラー層

@レスポンス本文
@PostMapping("/updateavatar")
    パブリック結果 updateAvatar(@RequestParam("username") String username,@RequestParam("file") MultipartFile file) は IOException をスローします {
        userService.uploadAvatar(ユーザー名,ファイル) を返します。
    }

サービス層はimplに直接実装されている

 // これはインポートされたツールキットであり、pom.xml にインストールする必要があります。 import cn.hutool.core.io.FileUtil;
    //ポート情報 @Value("${server.port}")
    プライベート文字列ポート;

    プライベート静的最終文字列 ip = "http://localhost";

    プライベート静的最終文字列static_root = "D:/devplatform_files";


    @オーバーライド
    パブリック結果 uploadAvatar(String username, MultipartFile file) は IOException をスローします {
        //元のファイルの名前を取得します。String originalFilename = file.getOriginalFilename();
// 文字列 rootFilePath = System.getProperty("user.dir")+"/src/main/resources/files/"+originalFilename;
        //ファイル パスを取得します。String rootFilePath = static_root + "/avatar/" + originalFilename;
        // ファイルに保存FileUtil.writeBytes(file.getBytes(),rootFilePath);
        //画像にアクセスするために使用するURL
        文字列 avatar = ip+":"+port+"/avatar/"+originalFilename;
        試す{
            //アバター情報をデータベースに保存します。userMapper.updateAvatar(avatar,username);
            // 自己カプセル化された結果結果の戻りクラス return Result.success(200,"アップロード成功",アバター);
        }catch (例外 e){
            System.out.println(e);
            Result.fail("アップロードに失敗しました"); を返します。
        }
    }

マッパー永続層

@マッパー
@リポジトリ
パブリックインターフェースUserMapper{
    文字列 getAvatarByUsername(文字列 ユーザー名);
}

mapper.xml ファイル

<?xml バージョン="1.0" エンコーディング="UTF-8"?>
<!DOCTYPE マッパー PUBLIC "-//mybatis.org//DTD マッパー 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<マッパー名前空間="com.devplatform.mapper.UserMapper">
    <update id="updateAvatar">
        ユーザーを更新し、アバターを #{avatar} に設定し、ユーザー名を #{username} に設定します。
    </更新>
</マッパー>

Resultクラスのカプセル化について

パブリッククラス Result {
    private int code; //200 は正常、200 以外は異常を示します private String msg;
    プライベートオブジェクトデータ。
    パブリック静的結果成功(オブジェクトデータ){
        success(200、"操作成功"、データ) を返します。
    }
    パブリック静的結果成功(文字列メッセージ){
        成功(200,msg,null)を返します。
    }
    パブリック静的結果成功(intコード、文字列メッセージ、オブジェクトデータ){
        結果 r = new Result();
        r.setCode(コード);
        r.setData(データ);
        r.setMsg(メッセージ);
        r を返します。
    }
    パブリック静的結果失敗(文字列メッセージ){
        失敗(400, メッセージ, null)を返します。
    }
    パブリック静的結果失敗(文字列メッセージ、オブジェクトデータ){
        失敗(400, メッセージ, データ)を返します。
    }
    パブリック静的結果失敗(intコード、文字列メッセージ、オブジェクトデータ){
        結果 r = new Result();
        r.setCode(コード);
        r.setData(データ);
        r.setMsg(メッセージ);
        r を返します。
    }
    public int getCode() {戻りコード;}
    パブリック void setCode(int code) {this.code = code;}
    パブリック文字列 getMsg() {return msg;}
    パブリック void setMsg(String msg) {this.msg = msg;}
    public Object getData() {データを返します。}
    パブリック void setData(オブジェクト データ) {this.data = data;}
}

イメージがクラウド サーバーに保存されると、URL を介して直接アクセスできるようになります。ここでは、この効果をローカルで示します。この効果が達成された場合にのみ、フロント エンドは img タグ内のイメージにアクセスできます。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • vue-cropper コンポーネントは画像の切り取りとアップロードを実現します
  • vue-cropperプラグインは、画像キャプチャとアップロードコンポーネントのカプセル化を実現します。
  • Vue画像切り抜きプラグインvue-cropperの使い方を詳しく説明します
  • Vue-cropper 画像切り抜きの基本原理とアイデア
  • Vue を cropper.js ベースでカプセル化し、オンライン画像切り抜きコンポーネント機能を実現する
  • vue-cropper を使用して vue で写真をトリミングする方法をご存知ですか?

<<:  docker compose の記述ルールについての簡単な説明

>>:  Workermanはmysql接続プールのサンプルコードを書きます

推薦する

MySQL パーティション テーブルの基本入門チュートリアル

序文最近のプロジェクトでは、大量のデータを保存する必要があり、このデータには有効期限があります。クエ...

Docker-compose を使用して Django アプリケーションをオフラインでデプロイする方法

目次開発環境用のDocker-ceをインストールする開発環境用のDocker-composeをインス...

MySQL NULLデータ変換方法(必読)

MySQL を使用してデータベースをクエリし、左結合を実行すると、関連付けられたフィールドの一部に...

LinuxシステムでFuserコマンドを使用する方法

Fuser コマンドとは何ですか? fuser コマンドは、特定のファイル、ディレクトリ、またはソケ...

Ubuntu 18.04 向け VMware Tools のインストールと構成のチュートリアル

この記事では、Ubuntu 18.04でのVMware Toolsのインストールと設定について記録し...

MySQLの数値型自動増分における落とし穴

テーブル構造を設計する場合、数値型は最も一般的な型の 1 つですが、数値型をうまく使用するのは想像す...

React Fiberの仕組みの詳細な説明

目次React Fiberとは何ですか?なぜReact Fiberなのか? React Fiberは...

mysqldump を使用した MySql のインポートおよびエクスポート方法の概要

データベースデータをエクスポートします:まずcmdを開いてMySQLのbinフォルダに入ります1. ...

Linux仮想マシンをWiFiに接続する方法

生活の中で、インターネットはどこにでもあります。インターネットを通じてゲームをしたり、テレビ番組を見...

js 配列 fill() 充填メソッド

目次1. fill() 構文2. fill() の使用3. まとめ序文:配列の初期化方法についてはよ...

タブ切り替え機能を実装するJavaScriptカスタムプラグイン

この記事では、タブ切り替え機能を実装するためのJavaScriptの具体的なコードを参考までに共有し...

Linux/CentOS サーバー セキュリティ構成の一般ガイド

Linux はオープン システムです。インターネット上には、既成のプログラムやツールが多数存在します...

process.env.NODE_ENV 本番環境モードを設定する方法

始める前に、process.env.NODE_ENV にはデフォルトで開発と本番の 2 つの状態しか...