[Android] Glide

๐Ÿ’ก์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ์ด๋ฏธ์ง€ ๋กœ๋”ฉ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ Glide์— ๋Œ€ํ•˜์—ฌ ํ•™์Šต ๋‚ด์šฉ์„ ๊ธฐ๋กํ•˜์˜€์Šต๋‹ˆ๋‹ค.

 

Glide

  • Glide๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ ์ด๋ฏธ์ง€ ๋กœ๋”ฉ ๋ฐ ์บ์‹ฑ์„ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, ๋„คํŠธ์›Œํฌ ๋˜๋Š” ๋กœ์ปฌ์—์„œ ์ด๋ฏธ์ง€๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ฐ€์ ธ์™€ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ, ๋””์Šคํฌ ์บ์‹œ, ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ง€์› ๋“ฑ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋ฉฐ, ํฐ ์ด๋ฏธ์ง€ ํŒŒ์ผ์ด๋‚˜ ๋น„๋™๊ธฐ ์ด๋ฏธ์ง€ ๋กœ๋“œ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

https://github.com/bumptech/glide

 

GitHub - bumptech/glide: An image loading and caching library for Android focused on smooth scrolling

An image loading and caching library for Android focused on smooth scrolling - bumptech/glide

github.com

 

Gradle

  • Glide๋ฅผ ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด build.gradle ํŒŒ์ผ์— ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
dependencies {
    implementation 'com.github.bumptech.glide:glide:4.15.1' // ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ
    kapt 'com.github.bumptech.glide:compiler:4.15.1' // Annotation Processor (Optional)
}

์ด๋ฏธ์ง€ ๋กœ๋”ฉ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ ์ด์œ 

  • ๋กœ์ปฌ์— ์žˆ๋Š” ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•˜์ง€๋งŒ, ๋„คํŠธ์›Œํฌ๋‚˜ ์บ์‹œ์—์„œ ๊ฐ€์ ธ์˜ฌ ๊ฒฝ์šฐ ๋ถˆ์•ˆ์ •ํ•˜๊ณ  ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๊ฒฝ์šฐ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์‚ฌ์šฉ์ž ์ž…์žฅ์—์„œ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ๊ณผ์ •๊ณผ ์ฒ˜๋ฆฌ๊ฐ€ ์ง„ํ–‰๋˜์–ด์•ผ ํ•˜๋ฉฐ, ์ด๋ฅผ ์‰ฝ๊ฒŒ ํ•ด๊ฒฐํ•ด์ค„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ์ด๋ฏธ์ง€ ๋กœ๋”ฉ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.
  • ์‚ฌ์šฉ์ž์—๊ฒŒ ์ด๋ฏธ์ง€๋ฅผ ๋ณด์—ฌ์ค„ ๋•Œ ์•„๋ž˜์™€ ๊ฐ™์€ ๊ณผ์ •์„ ๊ฑฐ์ณ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ์ด๋ฏธ์ง€ ์ „์ฒ˜๋ฆฌ : ์ด๋ฏธ์ง€๋ฅผ ๋กœ๋”ฉํ•˜๊ธฐ ์ „์— ์„ฌ๋„ค์ผ์ด๋‚˜ ์ง„ํ–‰ ์ƒํ™ฉ ํ‘œ์‹œ
  • ์ด๋ฏธ์ง€ ๋กœ๋”ฉ : ์บ์‹œ๋‚˜ ๋„คํŠธ์›Œํฌ์—์„œ ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์˜ด
  • ์ด๋ฏธ์ง€ ๋””์ฝ”๋”ฉ : BitmapFactory๋ฅผ ์ด์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€๋ฅผ ๋น„ํŠธ๋งต ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ํฌ๊ธฐ, ํšŒ์ „, ํ’ˆ์งˆ ๋“ฑ์„ ๋ณ€ํ™˜ํ•˜๋Š” ๋‹จ๊ณ„
  • ์ด๋ฏธ์ง€ ํ›„์ฒ˜๋ฆฌ : ๋ณด์—ฌ ์ค„ ์ด๋ฏธ์ง€์— ์• ๋‹ˆ๋ฉ”์ด์…˜์ด๋‚˜ ๋ชจ์„œ๋ฆฌ๋ฅผ ๋‘ฅ๊ธ€๊ฒŒ ํ•˜๋Š” ๋“ฑ์˜ ํšจ๊ณผ๋ฅผ ์ ์šฉ
  • ๋ณด์—ฌ ์ฃผ๊ธฐ : UI ์Šค๋ ˆ๋“œ์—์„œ ์ด๋ฏธ์ง€๋ฅผ ์ ์šฉํ•˜๋Š” ๋‹จ๊ณ„

Glide ์ ์šฉ

  • ์ผ๋ฐ˜์ ์œผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋ฉฐ, ๋งค์šฐ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ด๋ฏธ์ง€๋ฅผ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • placeholder()์™€ error()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€ ๋กœ๋“œ์™€ ์‹คํŒจํ•œ ๊ฒฝ์šฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
import com.bumptech.glide.Glide

Glide.with(context)
     .load("<https://example.com/image.jpg>") // ์ด๋ฏธ์ง€ URL ๋˜๋Š” ํŒŒ์ผ ๊ฒฝ๋กœ
     .into(imageView) // ์ด๋ฏธ์ง€๊ฐ€ ๋กœ๋“œ๋  ImageView
     .placeholder(R.drawable.placeholder) // ๋กœ๋”ฉ ์ค‘ ๋ณด์—ฌ์ค„ ์ด๋ฏธ์ง€
     .error(R.drawable.error_image) // ๋กœ๋”ฉ ์‹คํŒจ ์‹œ ๋ณด์—ฌ์ค„ ์ด๋ฏธ์ง€

๋น„๋””์˜ค ๋กœ๋“œ

  • ๋น„๋””์˜ค ํŒŒ์ผ๊ณผ ์ธ๋„ค์ผ์„ Glide๋กœ ๋กœ๋“œํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
Glide.with(context)
     .asBitmap() // ๋น„๋””์˜ค ์ธ๋„ค์ผ์€ Bitmap์œผ๋กœ ๋กœ๋“œ
     .load(Uri.fromFile(File("/path/to/video.mp4"))) // ๋น„๋””์˜ค ํŒŒ์ผ ๊ฒฝ๋กœ
     .into(imageView)

RequestOptions ํ™œ์šฉ

  • RequestOptions ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด ์ด๋ฏธ์ง€ ๋กœ๋“œ ์˜ต์…˜์„ ๋ณด๋‹ค ์„ธ๋ฐ€ํ•˜๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
val requestOptions = RequestOptions()
    .placeholder(R.drawable.placeholder)
    .error(R.drawable.error_image)
    .override(100, 100) // ์ด๋ฏธ์ง€ ํฌ๊ธฐ ์กฐ์ •

Glide.with(context)
     .load("<https://example.com/image.jpg>")
     .apply(requestOptions) // ์˜ต์…˜ ์ ์šฉ
     .into(imageView)

์บ์‹œ ์ „๋žต

  • ๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ์™€ ๋””์Šคํฌ ์บ์‹œ๋ฅผ ์ง€์›ํ•˜๋ฉฐ, ์ด๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์ด๋ฏธ์ง€๋ฅผ ๋น ๋ฅด๊ฒŒ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
val requestOptions = RequestOptions()
    .diskCacheStrategy(DiskCacheStrategy.ALL) // ๋””์Šคํฌ ์บ์‹œ ์‚ฌ์šฉ
    .skipMemoryCache(true) // ๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ ์‚ฌ์šฉ ์•ˆ ํ•จ

Glide.with(context)
     .load("<https://example.com/image.jpg>")
     .apply(requestOptions)
     .into(imageView)
  • DiskCacheStrategy.ALL: ๋ชจ๋“  ๋ฒ„์ „์„ ๋””์Šคํฌ์— ์บ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • DiskCacheStrategy.NONE: ๋””์Šคํฌ ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • DiskCacheStrategy.DATA: ๋กœ๋“œ๋œ ์ด๋ฏธ์ง€๋งŒ ๋””์Šคํฌ์— ์บ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • DiskCacheStrategy.RESOURCE: ๋ณ€ํ™˜๋œ ๋ฆฌ์†Œ์Šค๋ฅผ ์บ์‹œํ•ฉ๋‹ˆ๋‹ค.

Custom Transformation

  • Glide์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ณธ ๋ณ€ํ˜•(์›ํ˜•, ์ž๋ฅด๊ธฐ ๋“ฑ) ์™ธ์—๋„ ์ปค์Šคํ…€ ํŠธ๋žœ์Šคํฌ๋ฉ”์ด์…˜์„ ๊ตฌํ˜„ํ•˜์—ฌ ์œ ๋™์ ์ธ ๋ทฐ๋ฅผ ์ œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
class GrayscaleTransformation : BitmapTransformation() {

    override fun updateDiskCacheKey(messageDigest: MessageDigest) {
        messageDigest.update("grayscale".toByteArray())
    }

    override fun transform(
        pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int
    ): Bitmap {
        return toGrayscale(toTransform)
    }

    private fun toGrayscale(src: Bitmap): Bitmap {
        val width = src.width
        val height = src.height
        val bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bmpGrayscale)
        val paint = Paint()
        val colorMatrix = ColorMatrix()
        colorMatrix.setSaturation(0f)
        val filter = ColorMatrixColorFilter(colorMatrix)
        paint.colorFilter = filter
        canvas.drawBitmap(src, 0f, 0f, paint)
        return bmpGrayscale
    }
}

// ์‚ฌ์šฉ ์˜ˆ์‹œ
Glide.with(context)
     .load("<https://example.com/image.jpg>")
     .transform(GrayscaleTransformation()) // ๊ทธ๋ ˆ์ด์Šค์ผ€์ผ ๋ณ€ํ˜• ์ ์šฉ
     .into(imageView)

Glide ์žฅ์ 

  • ๋ฉ”๋ชจ๋ฆฌ ๋ฐ ๋””์Šคํฌ ์บ์‹œ ์ตœ์ ํ™”
  • ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šด API
  • GIF ๋ฐ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ด๋ฏธ์ง€ ์ง€์›
    • GIF์™€ ๊ฐ™์€ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ด๋ฏธ์ง€๋„ ์‰ฝ๊ฒŒ ๋กœ๋“œ ๋ฐ ์žฌ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ƒ๋ช…์ฃผ๊ธฐ ๊ด€๋ฆฌ
    • Activity or Fragment์™€ ์—ฐ๊ฒฐ๋˜์–ด ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ์ž๋™์œผ๋กœ ๊ด€๋ฆฌํ•˜๋ฉฐ, ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Glide vs Picasso

  • Picasso๋Š” Square์‚ฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ์ด๋ฏธ์ง€ ๋กœ๋”ฉ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž…๋‹ˆ๋‹ค.
  • Picasso๋Š” ์ด๋ฏธ์ง€๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ์ „์ฒด ํฌ๊ธฐ ์ด๋ฏธ์ง€๋ฅผ ์บ์‹œ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
    • ๋™์ผํ•œ ์ด๋ฏธ์ง€๋ฅผ ์š”์ฒญํ•  ๋•Œ๋งˆ๋‹ค ์ „์ฒด ํฌ๊ธฐ ์ด๋ฏธ์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ด๋ฏธ์ง€ ๋ณด๊ธฐ์— ๋งž๊ฒŒ ํฌ๊ธฐ๋ฅผ ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค.
  • Glide๋Š” ์ด๋ฏธ์ง€๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  View์˜ ํฌ๊ธฐ๋กœ ํฌ๊ธฐ๋ฅผ ์กฐ์ •ํ•œ ํ›„ ์บ์‹œ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  • ๋‘ ๊ฐœ์˜ ๋‹ค๋ฅธ ํฌ๊ธฐ์˜ ์ด๋ฏธ์ง€๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ, ๋™์ผํ•œ ์ด๋ฏธ์ง€๋กœ ๋‘ ๊ฐ€์ง€ ํ•ด์ƒ๋„๋กœ ์บ์‹œ์— ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Glide๋Š” Picasso์— ๋น„ํ•ด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ์ ์ง€๋งŒ ๋กœ๋”ฉ์ด ๋Š๋ฆฌ๋‹ค๋Š” ํŠน์ง•์ด ์žˆ์Šต๋‹ˆ๋‹ค.