画像ライブラリPicassoの使い方

![](http://square.github.io/picasso/static/sample.png)

[Jake Wharton](https://github.com/JakeWharton)率いる[Square](http://square.github.io/)が開発したAndroidの画像ダウンロードやキャッシュを「良い感じに」やってくれるライブラリ。

同等の事を実現するライブラリには[Universal Image Loader](https://github.com/nostra13/Android-Universal-Image-Loader)や[Volley](https://android.googlesource.com/platform/frameworks/volley/)のImageLoader等があるが，開発の活発さや導入コスト，サポート体制等も含めてSquareが管理しているものが一番モダンで信頼が置けるだろうとみた。

> Universal Image Loaderは詳細な設定オプションがあり便利だが、実装が一部冗長な為，Picassoの方がユーザーフレンドリーな印象を持ちました。が，状況に応じて使い分けるでもいいかも。

仕事で使う為にキャッシュの詳細な仕様やよく使うメソッドについて知見をまとめた。

## Picassoの良い所

- Adapter内でのImageViewのリサイクルやダウンロード処理のキャンセルを自動で実行してくれる
- 複雑な画像の変形処理を最小のメモリ消費で実現できる
- 自動でメモリ・ファイルキャッシュをやってくれる

## Download

```xml
<dependency>
  <groupId>com.squareup.picasso</groupId>
  <artifactId>picasso</artifactId>
  <version>2.3.3</version>
</dependency>
```

```groovy
compile 'com.squareup.picasso:picasso:2.3.3'
```

## Usage

公式ドキュメントに書いてるある様に，大体の場合1行で書く事ができる。

```java
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
```

`Picasso#with`メソッドでデフォルト値が設定されたPicassoインスタンスを生成している。内部では`Picasso#Builder`クラスのbuildメソッドがcallされている。

```java
public static Picasso with(Context context) {
  if (singleton == null) {
    synchronized (Picasso.class) {
      if (singleton == null) {
        singleton = new Builder(context).build();
      }
    }
  }
  return singleton;
}
```

## キャッシュ

[Javadoc](http://square.github.io/picasso/javadoc/index.html)にもあるが，withでインスタンスを生成した時のキャッシュ仕様は下記の通り。

#### メモリキャッシュ

- アプリで利用可能なRAMのうち15%を使用する。

```java
  static int calculateMemoryCacheSize(Context context) {
    ActivityManager am = getService(context, ACTIVITY_SERVICE);
    boolean largeHeap = (context.getApplicationInfo().flags & FLAG_LARGE_HEAP) != 0;
    int memoryClass = am.getMemoryClass();
    if (largeHeap && SDK_INT >= HONEYCOMB) {
      memoryClass = ActivityManagerHoneycomb.getLargeMemoryClass(am);
    }
    // Target ~15% of the available heap.
    return 1024 * 1024 * memoryClass / 7;
  }
```

#### ディスクキャッシュ

- ストレージのうち2%(5MB以上50MB)を自動で計算してくれる。ディスクキャッシュの期限は`Integer.MAX_VALUE`となっている。

> __デフォルトだとAPI Levelが14以上でないとディスクキャッシュは有効にならない(内部で`HttpResponseCache`を使用している為)。API Levelが14以下でディスクキャッシュを有効にする為には、Squareが独自開発している`OkHttp`をdependencyに組み込む。__

```java
 static long calculateDiskCacheSize(File dir) {
    long size = MIN_DISK_CACHE_SIZE;

    try {
      StatFs statFs = new StatFs(dir.getAbsolutePath());
      long available = ((long) statFs.getBlockCount()) * statFs.getBlockSize();
      // Target 2% of the total space.
      size = available / 50;
    } catch (IllegalArgumentException ignored) {
    }

    // Bound inside min/max size for disk cache.
    return Math.max(Math.min(size, MAX_DISK_CACHE_SIZE), MIN_DISK_CACHE_SIZE);
  }
```

自前の設定を差し込みたい場合は`Piccaso#Builder`クラスを利用してPicassoインスタンスを生成する。メモリキャッシュやファイルキャッシュの設定をいじりたい場合はDownloaderを実装したクラスを実装しBuilderに設定する。

## スレッドプール

- Three download threads for disk and network access.

	- `PicassoExecutorService`を確認する事。ネットワークの状態によってスレッドプールの数を変更している。

## よく使うメソッド

画像を都度柔軟に変更できるのがPicassoの強みで，提供されているメソッドはRequestCreatorクラスに生えている。よく使うものをピックアップした。

#### placeholder(int placeholderResId)

読み込み中の画像を設定する事ができる

#### error(int errorResId)

画像取得失敗時のメソッドを設定できる

#### into(Imageview imageview)

ImageView等を指定し、リクエストした画像を当て込む先を指定する。

#### centerCrop()

resizeメソッドによって指定された境界でアスペクト比を保ったまま切り取る。

#### centerInside()

resizeメソッドによって指定された境界でアスペクト比を保ったまま画像全てを表示。

#### fit()

指定したImageVIewの境界に合わせてresizeを実行してくれる。resizeメソッドと併用する事はできない。

#### resize(int targetWidth, int targetHeight)

指定したsize(px)で画像をリサイズする。

#### resizeDimen(int targetWidthResId, int targetHeightResId)

resizeと同じだが、dimes.xmlに指定したdpでリサイズを実行できる

#### rotate(float degrees)

画像を回転させる。

#### transform(Transformation transformation)

上記以外で画像の変形処理を自前で実装したい場合は、自前の`Transformation`を実装して設定してあげる。

```java
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()"; }
}
```

#### noFade()

デフォルトで実行されるフェードインを無効にする

## リソース読み込み

Resources, assets, files, content providers等の画像形式に対応している。

```java
Picasso.with(context).load(R.drawable.landing_screen).into(imageView1);
Picasso.with(context).load(new File(...)).into(imageView2);
```

## デバッグ

Picassoはデバッグすら気が利いている。

- `setLoggingEnabled(true)`する事で詳細なログが出力される。

- `setIndicatorsEnabled(true)`する事で、読み込まれた画像がネット、メモリ、ファイルキャッシュのどこから来たのか判定する事ができる。

![](http://square.github.io/picasso/static/debug.png)

## Document

javadocや専用のstackoverflowまであるのは嬉しい。

## 公式

- http://square.github.io/picasso/
- https://github.com/square/picasso

#### Javadoc

- http://square.github.io/picasso/javadoc/

#### StackOverFlow

- http://stackoverflow.com/questions/tagged/picasso?sort=active