2015年4月11日土曜日

[android]画像認識API(docomo developer support様ご提供)をvolleyを使ってリクエストする

読書日記にdocomo developer support様ご提供の画像認識APIを使って、カメラで撮った書籍画像から本の情報を取得するようにしました。
いやあ、こんなにすばらしいものを提供していただいて、本当にありがたいです。
画像認識用のSDKがありましたが、遅ればせながら最近導入したvolleyで実装することにしました。
volleyの基本的な使い方はTransmitting Network Data Using Volley等が詳しいです。

final byte[] imageBytes = ……
final String url = "https://api.apigw.smt.docomo.ne.jp/imageRecognition/v1/recognize?" +
                "APIKEY=YOUR_API_KEY" +
                "&recog=book" +
                "&numOfCandidates=1";

JsonObjectRequest jsObjRequest = new JsonObjectRequest
                (Request.Method.POST, url, null, new Response.Listener() {
                    @Override
                    public void onResponse(JSONObject jsonObject) {
                        Log.d("TAG", jsonObject.toString());
                        success(jsonObject);
                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.d("TAG", error.toString());
                        failed();
                    }
                }) {

            @Override
            protected Map getParams() {
                Map params = new HashMap<>();
                params.put("Content-Type", "application/octet-stream");
                return params;
            }

            @Override
            public byte[] getBody() {
                return imageBytes;
            }

        };

// あとはjsObjRequestをcom.android.volley.RequestQueueインスタンスにadd()すると通信が始まります。

通信結果はJSONで得られるので、JsonObjectRequestを使いました。
ポイントはPOSTであることと、JsonObjectRequestのgetParamsをOverrideしてContent-Typeの設定をすることと、getBodyをOverrideしてbyte[]つまりここでは画像データを返すようにすることです。
上記はnew JsonObjectRequestしたときにOverrideしていますが、JsonObjectRequestを継承して新たにクラスを作ったほうがよいのかもしれません。
通信結果はonResponse(JSONObject)でコールバックされます。
上記のsuccess()、failed()は私が作った適当なメソッドです。
byte[] imageBytesについては下記で補足します。

その他です。
・カメラ画像の取得はImage capture intentを参考にminimal codingしました。下記のようなintentを作ってActivity#startActivityForResult()する感じです。結果はもちろん、onActivityResultで得られます。
・getOutputMediaFileUri()はここに説明があります
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name

・撮影された画像はfileUri(android.net.Uriのインスタンス)に格納されているので、
File file = new File(fileUri.getPath());
FileInputStream inputStream = new FileInputStream(file);
byte[] imageBytes = ByteStreams.toByteArray(inputStream);
とでもすれば、byte[]が得られます。
com.google.common.io.ByteStreamsをつかっています。android studioへのguavaの追加方法はDependenciesあたりでしょうか。

0 件のコメント:

コメントを投稿