Nwht0xn1

Imgur APIを利用してWebブラウザから画像をアップロードするCreated on 2016-06-19 by r7kamura

Imgur という画像管理サービスがあり、このサービスは匿名で (Imgurにログインしたりせずに) 画像をアップロードできるAPIを提供している。今回、WikiHubに画像アップロード機能を付けるためにこのAPIを利用したので、実装方法を記録しておく。

下図は動かしてみている様子。

gif

Webブラウザに画像を与える

Imgur APIとは関係なく、そもそもWebブラウザにアップロードする画像を与えるには、例えば次のように様々な方法がある。

  • <input type="file" ...> にようなinput要素を利用して画像を選択する
  • ドラッグ&ドロップで画像を入力する
  • コピー&ペーストでクリップボードに格納された画像を入力する
  • base64形式でエンコードされた画像の文字列を与える
  • img要素から取り出す
  • canvas要素から取り出す

今回は、3つ目のコピー&ペーストで画像を与える方法を例にして説明する。

画像がペーストされたときに反応する

textarea要素上でクリップボードから文字列や画像などがペーストされると、pasteイベントが発生する。発生したイベント ClipboardEvent からは、以下のように複数のitemを取り出せる。それぞれのitemには、kindとtypeというプロパティが含まれている。kindプロパティを利用するとitemがファイルかどうかを、typeを利用するとitemが画像かどうかを判別できる。また、item.getAsFile() を利用すると、アップロードするための画像データを取り出せる。

ここまでのコードをまとめると、以下のようになる。DOM要素の探索、イベントハンドリング、Ajax通信、配列のイテレーション処理を簡略化するためにjQueryを利用している。

$('.js-example-textarea').on('paste', function (event) {
  $(event.originalEvent.clipboardData.items).each(function () {
    if (this.kind === 'file' && this.type.indexOf('image/') !== -1) {
      uploadImageToImgur(this.getAsFile());
    }
  });
});

Imgurに画像をアップロードする

Imgur APIのドキュメント を見ると、https://api.imgur.com/3/image にClient IDと画像データを送ると、アップロードされた画像のURLが得られることが分かる。Imgurは様々な形式で画像を受け付けてくれるが、今回は multipart/form-data形式で image というキーで画像データを含める方法を利用することにする。

ここまでのコードをまとめると、以下のようになる。

var uploadImageToImgur = function (blob) {
  var formData = new FormData();
  formData.append('image', blob);
  return $.ajax({
    contentType: false,
    data: formData,
    headers: {
      Authorization: 'Client-ID 0123456789abcde',
    },
    processData: false,
    type: 'POST',
    url: 'https://api.imgur.com/3/image'
  });
};

おしまい

これを上記のコードと組み合わせると、Imgurに画像をアップロードするためのコードが出来上がる。実際のWikiHubのコードでは、アップロード前にtextarea要素に ![image](Uploading image...) という文字列を追加したり、アップロード後に文字列を画像URLに置き換えたりということをしている。Imgurは非商用利用であれば自由に利用できるとあるので、使いどころ次第では便利に利用できるはず。Imgur APIのドキュメント に利用に関する制限について書いてある (例えば画像アップロードは1日1250枚までとか) ので、詳しくはこちらを。