【2021】WEBから画像を縦横比を維持してリサイズし、Cloud Storage for Firebaseに送信する方法

# 【2021】WEBから画像をリサイズしてCloud Storage for Firebaseに送信する方法

ロゴ画像をリサイズしてCloud Storage for Firebaseに送信する処理を実装しました。
base64, blobへの変換などに少し苦戦したので、新たに実装する方が少しでも早く行いたい処理を実現できるように共有します。

```index.html
<!-- 任意画像ファイルボタン（自分の場合はファイル選択ボタンをデフォルトのボタンではなく画像にしているためこのような実装になっているが、通常のファイル機能でもOK。） -->
<label>
<!-- ▽見せる部分 -->
<span class="filelabel" title="ファイルを選択">
<img src="images/camera.png"" width="32" height="26" alt="＋画像">
<!-- 選択 -->
</span>
<!-- 本来の選択フォームは隠す -->
<input type="file" name="datafile" id="logo-img-input" onChange="imgPreView(event)">
</label>

<div id="preview"></div>
<canvas id="for-resize-canvas" style="display: none;"></canvas>
<button id="send" class="btn btn-primary">SEND</button>

```

`style="display: none;`
に関しては、これをつけないともう一つ画像のViewができてしまうので、canvasを非表示にしています。
表示をしなくともリサイズ処理は問題なくできますので。

```index.js
//===画像プレビュー
function imgPreView(event) {
    let file = event.target.files[0];
    let reader = new FileReader();
    let preview = document.getElementById("preview");
    let previewImage = document.getElementById("previewImage");
    
    if(previewImage != null) {
        preview.removeChild(previewImage);
    }
    
    reader.onload = function(event) {
        let img = document.createElement("img");
        img.setAttribute("src", reader.result);
        /// プレビューに表示する画像のサイズ（Warning : リサイズするサイズではない）
        img.width = 200; 
        img.height = 200;
        img.setAttribute("id", "previewImage");
        preview.appendChild(img);
    };
    reader.readAsDataURL(file);
}

///アカウント情報の登録ボタンが押されたら
document.getElementById("send").onclick = function() {
    let files = document.getElementById('logo-img-input').files;
    //=== DBへ登録/更新
    if (files.length == 1) {
        console.log("ファイル選択ありの場合");
        ///===画像をリサイズ -> canvasへDraw -> blobe形式への変換処理（fileからではなくpreviewImageの画像を取得して使用する）
        let orgImage = document.getElementById('previewImage');
        let orgWidth  = orgImage.width;  // 元の横幅を保存
        let orgHeight = orgImage.height; // 元の高さを保存

        let targetImg = new Image();
        targetImg.src = $("#previewImage").attr('src');

        //横の長さをwidthとして指定し、縦横比を維持した縮小後の高さを計算
        let width = 300;
        let ratio = width / targetImg.width;
        let height = targetImg.height * ratio;
                    
        //canvasに描画
        let canvas = $("#canvas");
        let ctx = canvas[0].getContext('2d');
        $("#canvas").attr("width", width);
        $("#canvas").attr("height", height);
        ctx.drawImage(targetImg, 0, 0, width, height);    

        /// canvasから画像をbase64として取得する
        let base64 = canvas.get(0).toDataURL('image/jpeg');
        /// base64の値を表示して見る場合はここのコメントアウトを外す
        /// console.log("base64 : " , base64);

        /// base64から画像データを作成する
        let barr, bin, i, len;
        bin = atob(base64.split('base64,')[1]);
        len = bin.length;
        barr = new Uint8Array(len);
        i = 0;
        while (i < len) {
          barr[i] = bin.charCodeAt(i);
          i++;
        }
        blob = new Blob([barr], {type: 'image/jpeg'});
        /// blobの値を表示して見る場合はここのコメントアウトを外す
        // console.log("blob : " , blob);

        let file_path =  "/anyPathOf/" + "/outputImg.jpg";

        let logImgRef = firebase.storage().ref().child(file_path);
        logImgRef.put(blob).then(function(snapshot) {
          /// 画像の保存先URLを知りたい場合
          logImgRef.getDownloadURL().then(img_url => {
              console.log("savedImgUrl : ", img_url);
              /// 画像のURLが取得できたらDBへ登録の処理など
              /// [省略]
          });
        });
    }
    else {
        //===画像が設定されていない時の処理
        /// [省略]
    }
}
```

少しでも救われる方がいればと思います！

---
Twitterでも仲良くしてください！
https://twitter.com/funny_man_daa