"BOKU"のITな日常

BOKUが勉強したり、考えたことを頭の整理を兼ねてまとめてます。

WEBブラウザにドラッグ&ドロップした画像ファイルをBase64に変換する/javascript(jQuery)

f:id:arakan_no_boku:20191216111232p:plain 

目次

ドラッグ&ドロップした画像ファイルをBase64変換

ブラウザのWEB画面にドラッグ&ドロップした画像ファイルをBase64変換します。

なお、jQueryです。

ドラッグ&ドロップ処理を行うJavaScriptソース

dragdrop.jsです。

var obj = $("#dragandrophandler");
obj.on('dragenter', function (e) 
{
    e.stopPropagation();
    e.preventDefault();
    $(this).css('border', '2px solid #0B85A1');

});
obj.on('dragover', function (e) 
{
     e.stopPropagation();
     e.preventDefault();
     $("#dragandrophandler").css('background-color', '#ffffe0');
});
obj.on('drop', function (e) 
{
     $(this).css('border', '2px dotted #0B85A1');
     e.preventDefault();
     var file = e.originalEvent.dataTransfer.files[0];
    if(file.type === 'image/jpeg' || file.type === 'image/png') {
         //We need to send dropped files to Server
        const reader = new FileReader()
        reader.onload = () => {
            $("#imgdiv").children('img').attr('src', reader.result);
            $("#resultbase64").val(reader.result);
        }
        reader.readAsDataURL(file);    
        $("#dragandrophandler").css('background-color', '#ffffff');
    } else {
        alert("ドロップできるのは、JPEGPNG画像ファイルだけです");
    }

});
$(document).on('dragenter', function (e) 
{
    e.stopPropagation();
    e.preventDefault();
    $("#dragandrophandler").css('background-color', '#ffffff');

});
$(document).on('dragover', function (e) 
{
  e.stopPropagation();
  e.preventDefault();
  obj.css('border', '2px dotted #0B85A1');
});
$(document).on('drop', function (e) 
{
    e.stopPropagation();
    e.preventDefault();
});

補足します。

ポイント1:ファイルの受け取り

ドロップされたファイルを受け取ります。

var file = e.originalEvent.dataTransfer.files[0];

JPEGPNGファイルだけを受け付けます。

if(file.type === 'image/jpeg' || file.type === 'image/png')

あとは、FileReaderで画像ファイルを読み込み、「 reader.readAsDataURL(file);」で、Base64形式に変換します。

ポイント2:Base64形式への変換

readAsDataURL(file);は非同期に実行されます。

単純に戻り値で結果を受け取ることはできません。

なので、「reader.onload = () => {」のようにonloadイベントハンドラを定義して、その中でreader.resultにセットされた結果を受け取る必要があります。

reader.readAsDataURL(file);を実行すると、非同期に読み込み処理が動きます。

終了すると loadend イベントが生じて、同時に result プロパティにBase64エンコードしたデータがセットされます。

その結果は、reader.resultでとりだせますが、onloadイベントハンドラの外では参照できないので、以下のようにしています。

reader.onload = () => {
    $("#imgdiv").children('img').attr('src', reader.result);
    $("#resultbase64").val(reader.result);
}

ポイント3:JavaScriptに関係するHTML部分 

JavaScript「dragdrop.js」ではID固定で指定している箇所が3か所あります。

最初はドロップエリアです。

以下のような感じで定義されている想定です。

<div id="dragandrophandler" class="border col-lg-9">ここにJPEGまたはPNGファイルをドロップ</div>

 二つ目はドロップした画像を表示するエリアです。

同様に、以下のように定義されている想定です。

<div id="imgdiv" class="form-group row my-4">
    <img src="" />
</div>

です。

3つめは、textareaです。

今回は、サブミットした時に、requestにのせてPython側の処理に受け渡す想定の処理で作成したため、画像ファイルをBase64形式テキストにしていったんセットする必要があって、djangoのFormで非表示のtextareaを定義していて、これもIDを固定で使っていますが、そうでなければ必要ない部分でもあります。

参考までに、定義しているforms.pyをのせておきます。

forms.py

from django import forms


class UserForm(forms.Form):
    areaone = forms.CharField(
        label='',
        widget=forms.Textarea(
            attrs={
                'id': 'resultbase64',
                "rows": 20,
                "cols": 10,
            }
        )
    )

 

とりあえず実行イメージだけ

Python側のソースとかは掲載しませんが、上記のスクリプトを組み込んだDjangoのサンプル画面のイメージだけはっておきます。

f:id:arakan_no_boku:20191217222015p:plain

ここに、適当な画像ファイルをドロップしてみます。

f:id:arakan_no_boku:20191217222451p:plain

とりあえず、ドロップした結果が表示されました。

f:id:arakan_no_boku:20191217222722p:plain

今回はこんなところで。

ではでは。