BigImageViewer icon indicating copy to clipboard operation
BigImageViewer copied to clipboard

Implement CoilImageLoader

Open SkyleKayma opened this issue 4 years ago • 9 comments

Hi, any plan for supporting Coil image loading library ?

https://github.com/coil-kt/coil

Thx,

SkyleKayma avatar Feb 05 '20 08:02 SkyleKayma

PR is welcome!

Piasy avatar Feb 05 '20 10:02 Piasy

Before PR, is something like that suitable ? Or did I miss a very important notion? I wrote it quickly, there are obviously things to improve. It's based on what you have done for Glide.

I have never used Fresco, so I could not use it as a reference.

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Bitmap.CompressFormat
import android.graphics.drawable.BitmapDrawable
import android.net.Uri
import coil.Coil
import coil.api.load
import coil.request.RequestDisposable
import com.github.piasy.biv.loader.ImageLoader
import com.github.piasy.biv.metadata.ImageInfoExtractor
import timber.log.Timber
import java.io.File
import java.io.FileOutputStream
import java.io.OutputStream


/**
 * Created by Piasy{github.com/Piasy} on 09/11/2016.
 */
class CoilImageLoader(var context: Context, var imageLoader: coil.ImageLoader? = null) : ImageLoader {

    private val mRequestDisposableMap = hashMapOf<Int, RequestDisposable>()
    private val mImageLoader = imageLoader ?: Coil.loader()

    override fun loadImage(requestId: Int, uri: Uri, callback: ImageLoader.Callback) {
        val file = File(context.filesDir.toString(), "latestImageDownloaded.jpg")

        val disposable = mImageLoader.load(context, uri) {
            target(
                onStart = { callback.onStart() },
                onSuccess = { result ->
                    if (result is BitmapDrawable) {
                        saveBitmapToFile(file, result.bitmap, CompressFormat.JPEG, 100)
                    }
                    callback.onCacheHit(ImageInfoExtractor.getImageType(file), file)
                    callback.onSuccess(file)
                },
                onError = {
                    callback.onFail(Exception("Error on loading image with Coil"))
                }
            )
        }

        saveTarget(requestId, disposable)
    }

    private fun saveBitmapToFile(imageFile: File, bitmap: Bitmap, format: CompressFormat?, quality: Int) {
        val os: OutputStream
        try {
            os = FileOutputStream(imageFile)
            bitmap.compress(format, quality, os)
            os.flush()
            os.close()
        } catch (e: Exception) {
            Timber.e(e, "Error writing bitmap")
        }
    }

    override fun prefetch(uri: Uri) {
        // Do nothing
    }

    override fun cancel(requestId: Int) {
        clearTarget(requestId)
    }

    private fun clearTarget(requestId: Int) {
        mRequestDisposableMap.remove(requestId)?.dispose()
    }

    override fun cancelAll() {
        for (key in mRequestDisposableMap.keys) {
            cancel(key)
        }
    }

    private fun saveTarget(requestId: Int, disposable: RequestDisposable) {
        mRequestDisposableMap[requestId] = disposable
    }
}

Declared like this :

BigImageViewer.initialize(
    CoilImageLoader(applicationContext, ImageLoader(applicationContext) {
        // Custom params ...
        allowRgb565(false)
    })
)

We actually don't need to pass okHttpClient in parameters because we can create a custom ImageLoader from Coil like this:

ImageLoader(context) {
    okHttpClient {
        // Custom OkHttpClient
        OkHttpClient.Builder()
        .cache(CoilUtils.createDefaultCache(context))
        .build()
    }
}

SkyleKayma avatar Apr 03 '20 14:04 SkyleKayma

Looks cool. 👍

Piasy avatar Apr 04 '20 00:04 Piasy

Heyah! Any update on this? I'm currently planning on moving from Glide to Coil and would love to see Coil support in BigImageViewer.

EchoTiger avatar Aug 19 '20 18:08 EchoTiger

No. I didn't had time to work on it. What's given above is working like that, you can add it in your project, or better take it and do a PR. 😉

SkyleKayma avatar Aug 19 '20 18:08 SkyleKayma

I wrote up a test project to run a quick test, and it seemed that there was some errors with Coil.loader() and target Maybe the current/later versions of Coil have removed or changed this?

I'm not at all familiar with Coil at the moment, but once I get around to experimenting with it maybe I'll be able to figure out something. 😄

EchoTiger avatar Aug 19 '20 18:08 EchoTiger

Keep in mind that the above code saves each image into a file twice -- once when Coil downloads the image and once when saveBitmapToFile() is called. For large images, this can increase load times by a couple hundred milliseconds. It's also called on the main thread, resulting in many dropped framerates.

saket avatar Feb 14 '21 04:02 saket

try it https://github.com/mikaelzero/mojito/blob/master/coilimageloader/src/main/java/net/mikaelzero/coilimageloader/CoilImageLoader.kt

mikaelzero avatar Jul 27 '21 06:07 mikaelzero

Since Coil 2.x you can retrieve files from disk cache and there is no need to save them manually. I implemented ImageLoader interface for the latest Coil (2.1.0 at the moment) in this gist, check it out 👀

nikita-bushuev avatar Jul 25 '22 15:07 nikita-bushuev