Flickr APIを使ってみよう(3.写真を取得する)


Flickr APIを使ってみよう(2.写真を検索する)では写真を検索して、検索結果をjsonで取得するところまでを紹介しました。

今回はいよいよFlickrの醍醐味である写真を取得する方法を紹介します。

詳細は以下から。

jsonの解析

検索用APIで返却されるjsonの中身をみてみましょう。

下図はjsonのイメージ図です。

以下はtextオプションに”android”というテキストを渡して得られた結果です。

{ "photos": { "page": 1, "pages": "2989", "perpage": 100, "total": "298831",
    "photo": [
      { "id": "7188994342", "owner": "62328475@N00", "secret": "d30d2a3dbe", "server": "8143", "farm": 9, "title": "Talblick", "ispublic": 1, "isfriend": 0, "isfamily": 0 },
      { "id": "7188938614", "owner": "54550631@N02", "secret": "8782080dc7", "server": "7099", "farm": 8, "title": "anhphan:  Without TouchWiz, the Samsung Galaxy Note (with Android 4.0.3) is so much better !", "ispublic": 1, "isfriend": 0, "isfamily": 0 }
〜省略〜
    ] }, "stat": "ok" }

photos内のphotoアイテムの中に格納されている以下の情報が写真の取得に必要なものです。

  • farm
  • server
  • id
  • secret

以下は上記の情報を取得するために引数としてjsonを渡すとHashMapに格納するサンプルです。

HashMapのキーにjsonのキーを値にjsonの値を格納することで、jsonのキー指定で値を取得することができるので便利です。

private HashMap<String, String> parseJson(String json) {
    JSONObject jsonObj = null;
    try {
        jsonObj = new JSONObject(json);
    } catch (JSONException e) {
        Log.e(TAG, "jsonObj:" + e.toString());
        return null;
    }

    JSONObject photos = null;
    try {
        photos = jsonObj.getJSONObject("photos");
    } catch (JSONException e) {
        Log.e(TAG, "photos:" + e.toString());
        return null;
    }

    JSONArray photoArray = null;
    try {
        photoArray = photos.getJSONArray("photo");
    } catch (JSONException e) {
        Log.e(TAG, "photoArray:" + e.toString());
        return null;
    }

    JSONObject photoObj = null;
    Random rnd = new Random(System.currentTimeMillis());
    int ran = rnd.nextInt(photoArray.length());
    try {
        photoObj = photoArray.getJSONObject(ran);
    } catch (JSONException e) {
        Log.e(TAG, "photoObj:" + e.toString());
        return null;
    }

    HashMap<String, String> returnValue = new HashMap<String, String>();
    try {
        returnValue.put("farm", photoObj.getString("farm"));
        returnValue.put("server", photoObj.getString("server"));
        returnValue.put("id", photoObj.getString("id"));
        returnValue.put("secret", photoObj.getString("secret"));
    } catch (JSONException e) {
        Log.e(TAG, "photoSearchItem:" + e.toString());
        return null;
    }

    return returnValue;
}

12行目ではjsonのルート階層からphotos内のアイテムを取得しています。

20行目ではルート/photos階層からphoto内のアイテムを取得しています。
ルート/photos/photo/内のアイテムは複数個存在するため、JSONArrayクラスのオブジェクトから要素番号を指定して取得する必要があります。
27、28行目ではJSONArrayオブジェクトの要素数の範囲内でランダムに値を取得しています。
こうすることで、検索結果の中からランダムに写真を取得することができます。
30行目では要素番号を指定してJSONObjectを取得しています。

38〜41行目でJSONObjectから画像の取得に必要な情報を取得してHashMapに格納しています。

画像を取得する

画像を取得するためには以下の形式のURLを作成する必要があります。

http://farm{farm-id}.staticflickr.com/{server-id}/{id}_{secret}.jpg

このURLを作成してFlickrにリクエストを送信することで画像を取得することができます。

public Bitmap getFlickrImage(){
    String json = getPhotoData("0c38f12818af42840055523fe245afb5", "techbooster");
    HashMap<String, String> searchResult = parseJson(json);

    StringBuilder photoUrlSb = new StringBuilder();
    photoUrlSb.append("http://farm");
    photoUrlSb.append(searchResult.get("farm"));
    photoUrlSb.append(".staticflickr.com/");
    photoUrlSb.append(searchResult.get("server"));
    photoUrlSb.append("/");
    photoUrlSb.append(searchResult.get("id"));
    photoUrlSb.append("_");
    photoUrlSb.append(searchResult.get("secret"));
    photoUrlSb.append(".jpg");

    HttpClient client = new DefaultHttpClient();
    HttpParams httpparams = client.getParams();
    HttpConnectionParams.setConnectionTimeout(httpparams, 10000);
    HttpConnectionParams.setSoTimeout(httpparams, 10000);
    HttpGet httpGet = new HttpGet();
    // URIの設定
    try {
        httpGet.setURI(new URI(photoUrlSb.toString()));
    } catch (URISyntaxException e) {
        Log.e(TAG, "httpGet.setURI:" + e.toString());
        return null;
    }

    HttpResponse response = null;
    Bitmap bitmap = null;
    try {
         response = client.execute(httpGet);
         if (response.getStatusLine().getStatusCode() < 400) {
             InputStream in = response.getEntity().getContent();
             bitmap = BitmapFactory.decodeStream(in);
             if (in != null) {
                 in.close();
             }
             Log.d(TAG, String.valueOf(bitmap));
             return bitmap;
          }
    } catch (ClientProtocolException e) {
          Log.e(TAG, "getReaouse:" + e.toString());
          return null;
    } catch (IOException e) {
          Log.e(TAG, "getReaouse:" + e.toString());
          return null;
    }

    return bitmap;
}

1行目のgetPhotoDataメソッドは前回で作成した検索を行い検索結果のjsonを返却するメソッドです。

4行目〜13行目で画像取得用のURLを作成しています。

33行目でFlickrから取得した画像のストリームを取得しています。
このストリームをBitmapFactoryクラスのdecodeStreamメソッドの引数として渡すことでBitmapオブジェクトとして取得することができます。