FJCT_ニフクラ mobile backend(mBaaS)お役立ちブログ

スマホアプリ開発にニフクラ mobile backend(mBaaS)。アプリ開発に役立つ情報をおとどけ!

【Monaca×NCMB】画像のプレビューを表示&アップロードする方法(もくもく会より)

f:id:mbaasdevrel:20191224172324p:plain

NCMBでは毎月もくもく会を行っています。今はMonacaとNCMBのもくもく会として、何か困ったことがあればすぐにサポートできるようにしています。

そんなもくもく会でよくある質問を取り上げて記事化します。今回は画像をプレビューで表示して、そのままアップロードするというものです。

こんな時に使います

例えばソーシャルメディア系のアプリを作る、チャットアプリを作る、業務の報告アプリを作るなど様々な場面でカメラが使われるはずです。そのカメラで撮影した写真をプレビューに表示して、問題なければアップロードするというのはよくあることでしょう。そんな場面で使えそうなテクニックです。

HTMLについて

HTMLは次のようになります。まずファイルを選択するinputを置きます。

<input type="file" id="file" accept="image/*" />

次に選択された写真をプレビューする場所を置きます。

<div id="preview">
  <h2>プレビュー</h2>
  <div id="name"></div>
  <img width="200px" />
</div>

後はアップロード処理と、アップロードがうまくいった時に、その確認として写真を表示する場所を置きます。

<button id="btn">アップロード</button>

<div id="mbaas">
  <div id="result"></div>
  <img width="200px" />
</div>

JavaScriptについて

mBaaSの初期化

まず最初はmBaaSを初期化します。appIdというのは管理画面のURL上部に記載されている文字列です。HTTPSでファイルにアクセスする際に用います。

// 定数の指定
const applicationKey = '53ee32f8cc60c24703fecd6e121cabb710c71c46f288b5864a64845c558d1fff';
const clientKey = '3bafaebfa7a4fa9470ed7edf0a7e3811228f61e5ae930929cd49dce421311bbf';
const appId = 'pYd5Qf9Qyn3F7uES';

// NCMBの初期化
const ncmb = new NCMB(applicationKey, clientKey);

この部分です。

f:id:mbaasdevrel:20191224172342p:plain

プレビューまで

ではファイル選択してからプレビューで表示するまでの処理です。一つ一つの処理はコメントを読んでください。

// よく使うので関数化
const $ = (name) => document.querySelector(name);

// 画像を選択した際の処理
$('#file').addEventListener('change', (e) => {
    // 画像を取得
  const file = e.target.files[0];
  // ファイル読み込み用
  const fileReader = new FileReader();
  // ファイルを読み込んだ時のコールバック
  fileReader.onload = function() {
    // dataURIをそのまま指定
        $('#preview img').src = this.result;
  }
  // ファイル名を残しておく
  $('#name').innerText = file.name;
  // dataURIとしてファイルを読み込む
  fileReader.readAsDataURL(file);
});

コツはdataURIとしてファイルを読み込むことです(fileReader.readAsDataURL(file))。そのためFileReaderを使って選択された写真を読み込みます。その結果( this.result )を画像のsrc要素に適用します。

ファイルのアップロード

ファイルのアップロード処理は次のようになります。一つ一つの処理はコメントを読んでください。

// mBaaSへのアップロード処理
$('#btn').addEventListener('click', async (e) => {
    // dataURIになっている画像リソースを取得
    const dataURI = $('#preview img').src;
  // dataURIをBlobに変換する
  const blob = toBlob(dataURI);
  // ファイル名を取得
  const fileName = $('#name').innerText;
  try {
    $('#result').innerText = 'アップロード中…';
    // ファイルアップロード処理
    await ncmb.File.upload(fileName, blob);
    $('#result').innerText = '成功';
    // 完了したらHTTPSアクセスで画像表示
    $('#mbaas img').src = `https://mbaas.api.nifcloud.com/2013-09-01/applications/${appId}/publicFiles/${fileName}`;
  } catch (e) {
    // 失敗したらエラーを表示
    $('#result').innerText = '失敗';
  }
  
});

// dataURIをBlobに変換する関数
const toBlob = (dataURI) => {
    const byteString = atob( dataURI.split( "," )[1] ) ;
    const mimeType = dataURI.match( /(:)([a-z\/]+)(;)/ )[2] ;
    for( var i=0, l=byteString.length, content=new Uint8Array( l ); l>i; i++ ) {
        content[i] = byteString.charCodeAt( i ) ;
    }
    return new Blob( [ content ], {
        type: mimeType ,
    }) ;
}

注意点としてはdataURIのままアップロードはできないので、toBlob(上記後半)の関数を使ってBlob型にします。後はファイル名を付けてアップロード( await ncmb.File.upload(fileName, blob); )を実行します。

アップロードが完了したら、画像を表示します。この際HTTPSアクセスできるURLは https://mbaas.api.nifcloud.com/2013-09-01/applications/ までが全アプリで共通であり、その後にアプリIDと /publicFiles という文字、最後にアップロードしたファイル名が続きます。

ここまでの処理をアニメーションGIFにしたものが下の画像になります。

f:id:mbaasdevrel:20191224172128g:plain

注意点

画像へのHTTPSアクセスを有効にするため、管理画面で設定を行ってください。

f:id:mbaasdevrel:20191224172324p:plain

まとめ

今回の処理を体験できるURLを用意しました。実装時の参考にしてください。

JSFiddle

Monaca × NCMBもくもく会は毎月開催しています。集中してアプリ開発に勤しむ時間、そして何か困ったことがあったらすぐに解決できる場所として活用してください!

ニフクラ mobile backend - connpass

中津川 篤司

中津川 篤司

NCMBエヴァンジェリスト。プログラマ、エンジニアとしていくつかの企業で働き、28歳のときに独立。 2004年、まだ情報が少なかったオープンソースソフトの技術ブログ「MOONGIFT」を開設し、毎日情報を発信している。2013年に法人化、ビジネスとエンジニアを結ぶDXエージェンシー「DevRel」活動をスタート。