[séns]

tomoyukim's blog

本ブログはMediumへ移行しました。
https://medium.com/tomoyukims-blog

Picasso : 画像読み込み・キャッシュ・表示の為のAndroidライブラリ

f:id:tomoyukim:20140424093505j:plain

最近のイカしたモダンなAndroid ライブラリ?Picassoを使ってみましたので紹介。

GridViewに画像をWebから取得してきて、表示するという処理をしようとしていたのですが、AsyncTaskはスレッド数制限が多いのでThreadPool使って抑えつつ、LruCacheでメモリキャッシュしたり…と考えていたら全部やってくれるやつがいました!

Picasso - Square Open Souce

非常にシンプルで使いやすいライブラリです。画像のロード、表示、キャッシュまでやってくれます。
上記からjarをDLして自分のプロジェクトにimportします。

そしてSquareは、あのSquareです。
ジャック・ドーシー率いるカード決済ベンチャーの開発チームが公開しているオープンソースです。

GridView に画像を表示する

できることや使い方の詳細はGithubやSampleがあるので、そちらが参考になりますが、今回使ったGridViewのところは掲載しておきたいと思います。

import com.squareup.picasso.Picasso;

public class ImageAdapter extends BaseAdapter {
    private Context mContext;
    protected ArrayList<Item> itemList;
    private static LayoutInflater inflater = null;

    public ImageAdapter(Context c, ArrayList<Item> list) {
        mContext = c;
        itemList = list;
        inflater = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public int getCount() {
        return itemList.size();
    }

    public Object getItem(int position){
        return null;
    }

    public long getItemId(int position) {
        return 0;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        View rowView;

        if (convertView == null) {
            rowView = inflater.inflate(R.layout.grid, null);
            rowView.setPadding(4,4,4,2);
        } else {
            rowView =  convertView;
        }

        ImageView img = (ImageView) rowView.findViewById(R.id.imageView1);
        img.setScaleType(ImageView.ScaleType.CENTER_CROP);

        Picasso.with(mContext).load((String)itemList.get(position).getImageUrl()).transform(new CropSquareTransformation()).resize(250,250).into(img);

        return rowView;
    }
}

GridViewにセットするAdapterClassはこんな感じです。 ArrayListには各Itemで表示するための画像のURLが格納されています。

Picasso.with(mContext).load((String)itemList.get(position).getImageUrl()).transform(new CropSquareTransformation()).resize(250,250).into(img);

Picassoを使っていますが、非常に軽量に動作しています。

とりあえずで使っていたシンプルなAsyncTaskだとXperia Z1でも相当重いですし、PoorなデバイスだとOutOfMemoryしました。
そもそもキャッシュを考慮しないとURLへのアクセスも増えるので、その辺の処理用に画像処理用クラスを用意していたのですが、それがそのままマルっとこの1行に収まった感じです。

画像の変形をカスタマイズする

ちなみに、.transform(new CropSquareTransformation())は公式サイトにあるコードををのまま使っています。画像を正方形に整形するコードです。

import com.squareup.picasso.Transformation;

public class CropSquareTransformation implements Transformation {
  @Override public Bitmap transform(Bitmap source) {
    int size = Math.min(source.getWidth(), source.getHeight());
    int x = (source.getWidth() - size) / 2;
    int y = (source.getHeight() - size) / 2;
    Bitmap result = Bitmap.createBitmap(source, x, y, size, size);
    if (result != source) {
      source.recycle();
    }
    return result;
  }

  @Override public String key() { return "square()"; }
}

ここでは正方形に整形してから、250x250にリサイズすることで画像サイズを小さくしてメモリへの影響を抑えています。

例えば、アスペクトを保ったまま小さくしたいとか、画像のサイズによって処理を変えたいなど、画像に対する編集はこのTransformインターフェイスをOverrideすることでカスタムできそうです。