デスクトップ(Windows)からのドラッグ&ドロップで画像データをテキスト化(base64)する

画像をデータベースに登録するときにPHP側で変換処理するよりもやっぱりJavascriptで行なえば楽だろうな?と思ってみたものの、最近時間がなかった。
ちょっと暇になったので作ってみた。
やっぱりコーディングに時間がかかってしまった。ほぼ徹夜になっちゃったぜ。

<!DOCTYPE hrml>
<head>
  <meta charset="utf-8">
  <title>画像文字変換</title>

<style>
  #A { width: 100px; height: 100px; border: 4px red solid; }
  #B { border: 4px solid #f80; }
  p * { vertical-align: top; }
</style>


<body>
<h1>Drag&Dropでイメージ画像をbase64で文字に変換する</h1>
<p>
  イメージファイルを文字列(base64)化出来れば、
  データベースへの登録も簡単に済ませられそうなので実験する
</p>

<p>
  下の赤枠に画像をドロップします<br>
  Image: <img id="A" alt="Image">
</p>

<p>
  base64:
  <textarea id="B" cols="70" rows="10"></textarea>
</p>


<script>
{
  const
    FILE_MAX_SIZE = 65535,
    FILE_TYPE     = 'image/';

  //___________________

  const
    init_loader =
      function () {
        let
          { reader, file } = this,
          chk = fileCheck (file);
        
        if (chk)
          throw new Error ('Error!! (' + chk + ')');

        reader.addEventListener ('load', this, false);
        reader.readAsDataURL (file);
      },


    fileCheck =
      function (file) {
        return (
          ((! file)) +
          ((0 !== file.type.indexOf (FILE_TYPE)) << 1) +
          ((FILE_MAX_SIZE < file.size) << 2)
        )
      };



  class ImageLoader {

    constructor (file, cbFunc = null, cbObj = null) {
      this.reader = new FileReader ();
      this.file = file;
      this.cbFunc = cbFunc;
      this.cbObj = cbObj;

      init_loader.call (this);
    }


    handleEvent (event) {
      this.cbFunc.call (this.cbObj, this.reader.result);
    } 
  }
  
  
  this.ImageLoader = ImageLoader;


  //___________________

  const

    init_dndfd =
      function () {
        let {target} = this;
        target.addEventListener ('dragover', this, false);
        target.addEventListener ('drop', this, false);
        target.dropzone = 'copy';
      };


  class DnDfromDeskTop {

    constructor (target, cbFunc, cbObj) {
      if (1 > arguments.length)
        throw new Error ('引数が不足しています');
      
      this.target = target;
      this.cbFunc = cbFunc;
      this.cbObj  = cbObj;
      
      init_dndfd.call (this);
    }


    handleEvent (event) {
      event.stopPropagation ();
      event.preventDefault();

      switch (event.type) {
      case 'drop' :
          this.cbFunc.call (this.cbObj, event.dataTransfer.files);
          alert(1);
          break;
      
      case 'dragover' : event.dataTransfer.dropEffect = 'copy'; break;      
      }
    }

  }
  
  this.DnDfromDeskTop = DnDfromDeskTop;
}


//###########################################################################################

//デスクトップからドラッグアンドドロップでファイルが指定されたら
new DnDfromDeskTop (document.querySelector ('#A'), getDesktop);

//ドロップされたファイルを読み込ませる
function getDesktop (files) {
  if (files.length) //複数選択されるかもしれないので1つだけ
    new ImageLoader (files[0], setting);
}

//読み込んだイメージをテキスト化したものを代入する
function setting (str) {
  document.querySelector ('#A').src = str;
  document.querySelector ('#B').value = str;
}

</script>