画像読み込みライブラリCoil導入ガイド
こんにちは。
note Androidアプリで、画像読み込みライブラリCoilを導入しましたので、それについて書いていこうと思います。
※ この記事はnote株式会社のアプリチーム1weekアドベントカレンダーの4日目の記事です
Coilとは
画像読み込みライブラリCoilは、Android用の画像読み込みライブラリです。
Coilの名称は「Coroutine Image Loader」の略です。
主な特徴はこちら。
導入
mavenCentralで導入できます。
implementation("io.coil-kt:coil:2.6.0")
バージョンはこちらから参照してください。(Release)
画像取得
CoilはImageViewの拡張関数のloadを使用して、画像を取得します。
// URL
imageView.load("https://example.com/image.jpg")
// File
imageView.load(File("/path/to/image.jpg"))
画像を読み込むだけだと上記のみですので、コード量が少なくて実装が楽な印象ですね。
各種設定
画像を読み込む際に、各種設定を行うことができます。
設定については、ラムダ式を使用して行います。
ここでは、よく使用した設定について解説していこうと思います。
imageView.load("https://example.com/image.jpg") {
crossfade(true)
placeholder(R.drawable.placeholder)
error(R.drawable.error)
scale(Scale.FILL)
size(width, height)
transformations(CircleCropTransformation())
}
crossfade: クロスフェード アニメーションを有効かどうか。デフォルトはfalse。
placeholder: プレイスホルダーの画像を設定。Drawableと @DrawableRes Intが設定可能。
error: 画像を読み込みに失敗した際に表示する画像を設定。Drawableと @DrawableRes Intが設定可能。
scale: 画像を指定されたサイズに合わせるために使用されるスケーリングを設定。Scaleは FILLとFIT。設定されていないとImageViewに対して自動的に計算されます。
size: 画像のサイズを設定。@Px Intを設定可能。
transformations: 返される画像の形を設定。CircleCropTransformation()で円画像。RoundedCornersTransformation()で丸角画像に変換でき、radiusの設定も可能です。
Jetpack Compose
CoilはJetpack Composeにも正式対応しています。
ただ、別途mavenCentralで導入する必要があります。
implementation("io.coil-kt:coil-compose:2.6.0")
バージョンは上記のCoilと同様。
AsyncImageを使用して、画像読み込みを行えます。
AsyncImage(
model = ImageRequest.Builder(LocalContext.current)
.data("https://example.com/image.jpg")
.crossfade(true)
.build(),
placeholder = painterResource(R.drawable.placeholder),
contentDescription = stringResource(R.string.description),
contentScale = ContentScale.Crop,
modifier = Modifier.clip(CircleShape)
)
各画像フォーマットに対応する
対応フォーマット
Coilを導入することで下記のフォーマットは標準で対応しています。
また、追加で下記フォーマットも設定することで使用できます。
アディショナルのフォーマットを導入
mavenCentralから追加で導入。
implementation("io.coil-kt:coil-gif:2.6.0")
implementation("io.coil-kt:coil-svg:2.6.0")
implementation("io.coil-kt:coil-video:2.6.0")
ImageLoaderにcomponentsを追加。
val imageLoader = ImageLoader.Builder(context)
.components {
add(ImageDecoderDecoder.Factory())
add(SvgDecoder.Factory())
add(VideoFrameDecoder.Factory())
}
.build()
上記の設定を行うことで、自動で各フォーマットを認識して対応してくれます。
ヘッダー設定
画像を読み込む際に、カスタムヘッダーを追加したい場合もあると思います。
Coilでは、Okhttpを使用しているのでOkhttpと同じように設定することが出来ます。
1. Interceptorを設置
class CustomHeaderInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val newRequest = request.newBuilder()
.addHeader("header", "header")
.build()
return chain.proceed(newRequest)
}
}
2. ImageLoaderに設定
val imageLoader = ImageLoader.Builder(context)
.okHttpClient {
OkHttpClient.Builder()
.addInterceptor(CustomHeaderInterceptor())
.build()
}
.build()
画像取得後に処理を行う
画像をプリロードしたり、取得した後に何か処理をしたい場合にも対応できます。
targetを設定することで、成功時、失敗時の処理を行えます。
val request = ImageRequest.Builder(context)
.data("https://example.com/image.jpg")
.target(
onSuccess = { result ->
// 成功時の処理
},
onError = {
// 失敗時の処理
},
).build()
imageLoader.enqueue(request)
共通設定
今までの上記設定は個別に設定できますが、アプリ内で共通の設定を行うことでコードを簡略化することができ、とても便利です。
1. ApplicationクラスにImageLoaderFactoryを継承
class App : Application(), ImageLoaderFactory
2.newImageLoader()内に共通化したい処理を記述する
override fun newImageLoader(): ImageLoader {
val imageLoader = ImageLoader.Builder(applicationContext)
.okHttpClient {
OkHttpClient.Builder()
.addInterceptor(CustomHeaderInterceptor())
.build()
}
.components {
add(ImageDecoderDecoder.Factory())
add(SvgDecoder.Factory())
add(VideoFrameDecoder.Factory())
}
.crossfade(true)
.build()
return imageLoader
}
導入してみて
導入してみて、とても実装が楽だなと感じました。
ラムダ式で設定を書くのは現状の実装では馴染みがあり、すぐに順応できたと思います。
各種カスタマイズもやりやすく、ヘッダー設定や共通処理は簡単にできたと思っています。
また、ImageViewの拡張関数として書けるので、他のライブラリに比べてコード記述量が削減できていました。
パフォーマンスに関しても、今のところ申し分なく感じています。
note AndroidアプリはJetpack Composeへ徐々に移行していっているのですが、Jetpack Composeに正式対応しているところもいいところだなっと思います。
今、一番ホットな画像読み込みライブラリだと思うので、この記事を読んで導入するきっかけになればと思います。
参考
最後に
現在、noteではAndroidエンジニアを絶賛募集中です!
カジュアル面談もやっていますので、
どんなことをやっているのか、どんな開発環境でやっているか等の気になることがありましたら、ぜひお気軽にお問い合わせください。