Azure Computer Vision API と Azure StorageのJavaSDKを使ってファイルアップロードシステムを作ってみよう

どーもです。まーやです。

Azure Cognitive Services のうちの一つである Computer Vision API と Azure のJava SDKの一つである Microsoft Azure Storage SDK for Java を使って簡単なシステムを作って見たいと思います。

# Agenda
- 今回の作ったもの
- Cognitive Services Computer Vision API サムネイル作成機能
- Storage を Java SDKから使おう
- 実際にやってみた雑感など
- まとめ

# 今回作ったもの
今回は簡易ファイルアップロードシステムを作成しました。とにかく使ってみること第一で作ったので、作り込みとかしてません。
![Untitled.png](https://qiita-image-store.s3.amazonaws.com/0/60850/b824eba7-ab4e-bf82-5997-1e981015aa70.png)

機能①：画面からファイルをアップロードし、画面に表示する
機能②：アップロードしたファイルは自動でサムネイル画像を作成し、同時に保存する

システムの基盤は[Spring Boot](https://projects.spring.io/spring-boot/)、html表示やformデータのやりとりなどは[Thymeleaf](http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf_ja.html#thymeleafの紹介)を使用しました。
Spring Boot内でAzure SDKを使用して、Storageとのやりとりを行います。

出来上がりイメージはこちら。BootStrapテンプレートをありがたく使用させていただきました。

左側にあるファイルアップロード部分からファイルをアップロードすると
![スクリーンショット 2016-12-27 22.12.13.png](https://qiita-image-store.s3.amazonaws.com/0/60850/bad7ee53-c997-7e2b-32af-302f16282e5b.png)

表示されるファイルが増えるよ
![スクリーンショット 2016-12-27 22.14.35.png](https://qiita-image-store.s3.amazonaws.com/0/60850/53714e2f-592a-c5c3-302a-c31ce5bcb382.png)

クリックすると元画像が表示されるよ
![スクリーンショット 2016-12-27 22.17.03.png](https://qiita-image-store.s3.amazonaws.com/0/60850/6fc5950c-7d42-721b-c96c-11c1796211c2.png)

# Cognitive Services Computer Vision API サムネイル作成機能
サムネイル画像の加工には、今回は[Computer Vision API](https://azure.microsoft.com/ja-jp/services/cognitive-services/computer-vision/)を使用しました。Computer Vision APIは元々は人の顔や表情を判別したり、何が写っているかを分析・分類するためのAPIですが、その機能の副産物として、「いい感じのサムネイル画像を作成する」という機能も兼ね備えています。

「いい感じ」というのは「何が写っているかわかりやすい」という意味で捉えていただければOKです。被写体が右に寄っている場合、何も考えずに画像の切り取り加工をしてしまうと何が写っている写真だかよくわからないサムネイル画像になってしまいますよね。Computer Vision APIを使うと、被写体の位置を分析し、被写体周りを指定したサイズで切り取り、サムネイル画像を作成してくれます。

例えばこの写真を
![buzz.jpg](https://qiita-image-store.s3.amazonaws.com/0/60850/f241e98c-fbf1-e4bf-2167-e28fa961cb25.jpeg)

何も考えずに左上で切り取ったサムネイルにすると↓のようになってなんの写真かわからないサムネイルが出来上がりますが
![buss1.jpg](https://qiita-image-store.s3.amazonaws.com/0/60850/f90bce26-edb4-5182-3db2-2daa756c6e13.jpeg)

Computer Visionに解析してもらって、サムネイルを作成すると「いい感じ」になります↓
![IMG_1351のコピー2.jpg](https://qiita-image-store.s3.amazonaws.com/0/60850/681dfbfc-ff11-27c8-915b-f9a55805fdb1.jpeg)

自分の写真でまず色々試して見たい方は[demoページ](https://www.microsoft.com/cognitive-services/en-us/computer-vision-api)がありますので試して見てください。
その他料金や他の機能なども見て見たい方は[こちら](http://qiita.com/maaya8585/items/64a324f5649acffd7b3e)もよろしければご参考ください。

Cognitive ServicesはAPIを直接叩いて操作します。

# Storage を Java SDKから使おう
[Azure Storage](https://azure.microsoft.com/ja-jp/services/storage/?wt.mc_id=JP_ABG_CLD_PD_SEM_BRWT.srch=1&wt.mc_id=AID529441_SEM_PQXkhRix)はファイルストレージサービスです。BLOB/ファイル/キュー/テーブルなど様々な形でデータ保存することができます。今回のシステムでは、このStorageにコンテナ(ディレクトリ)を作成し、BLOBとして元画像とサムネイル画像を保存します。

今回はSDKの一つである[Microsoft Azure Storage SDK for Java](https://github.com/azure/azure-storage-java) を使用しました。Azure のJava SDKはこのほかにもサービスごとに色々と用意されているので、利用するサービスのSDKをうまくチョイスして使うようにしましょう。Java用のSDKは[Maven リポジトリ](http://search.maven.org/#search%7Cga%7C3%7CAzure) にあがっています。

Gradle で依存性を追加してあげればOK。

```
dependencies {
　　　　　　　　・・・・・・
　　　　　　　　　　compile 'com.microsoft.azure:azure-storage:4.0.0'
　　　　　　　　・・・
}
```

使い方のサンプルは[こちら](https://docs.microsoft.com/ja-jp/azure/storage/storage-java-how-to-use-blob-storage)にありましたので参考にしてください。
そのほかJava関係のサポートは[こちら](https://azure.microsoft.com/ja-jp/develop/java/)にまとまっています。


# 実際にやってみた雑感など
Computer Visionで使える画像サイズの上限が決まっているのですが、今回は画像サイズの調整やチェック処理さえついてないです・・・というわけで上限以上のファイルサイズの画像をアップロードするとシステムエラー的な何かが発生します・・・。後々改善したいと思います。。。

Java SDKについては、最初情報が乏しかったため「一体どれを使えばいいんだ・・・」と途方にくれながらMavenリポジトリを眺めていたんですが、目当てのものが見つかってしまえばあとは依存関係セットするだけ、利用についてはそんなに苦労せずに使い始めることができました。すんなりファイルのアップロードや一覧取得できましたよ。

いけてないなーと思ったのは[Computer Vision サムネイルAPIのデモページ](https://dev.projectoxford.ai/docs/services/56f91f2d778daf23d8ec6739/operations/56f91f2e778daf14a499e1fb/console)。これ、レスポンスがバイナリなのでめっちゃ文字化けして返却されるんですよ。[Javaコードサンプル](https://dev.projectoxford.ai/docs/services/56f91f2d778daf23d8ec6739/operations/56f91f2e778daf14a499e1fb)にもあったんですが、どうやら一番最後に `EntityUtils.toString(entity)` をしているようなのです。画像データを文字列にしてたらまぁそうなりますよね、っていう。せっかくのAPIのデモページなので、レスポンスには是非画像が表示されて欲しいところです。

ちなみに画像化するためにはドキュメント上にあるJavaコードサンプルをそのまま使うためにはentity(取得した画像データ)を `getContent()` する必要があります。[こんな感じになります](https://github.com/mahya8585/ComputerVisionSandbox/blob/master/src/main/java/jp/co/opst/cloud/study/domain/helper/AzureComputerVisionHelper.java#L53)。

最後に、今回作成したコードは[GitHub](https://github.com/mahya8585/ComputerVisionSandbox)にあげてみました。正直まだ雑に動くようになっただけなので、もう少し修正やREADMEを充実させていきたいと思います。

# まとめ
Azure StorageもComputer VisionもまだまだJavaとの関連情報が少ないので、もっと充実すると敷居が下がって良いのではないかなと思いました。
あとAzureのサービス全部をJavaから使えるわけではないのが現状で、使いたいサービスでJava(とPython)が使えない、なんてこともしばしばなので、もっと使える領域が増えたらいいなと思います。

以上でした。