Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement CoilImageLoader #191

Open
SkyleKayma opened this issue Feb 5, 2020 · 9 comments
Open

Implement CoilImageLoader #191

SkyleKayma opened this issue Feb 5, 2020 · 9 comments

Comments

@SkyleKayma
Copy link

Hi, any plan for supporting Coil image loading library ?

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

Thx,

@Piasy
Copy link
Owner

Piasy commented Feb 5, 2020

PR is welcome!

@SkyleKayma
Copy link
Author

SkyleKayma commented Apr 3, 2020

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()
    }
}

@Piasy
Copy link
Owner

Piasy commented Apr 4, 2020

Looks cool. 👍

@EchoTiger
Copy link

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

@SkyleKayma
Copy link
Author

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. 😉

@EchoTiger
Copy link

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. 😄

@saket
Copy link

saket commented Feb 14, 2021

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.

@nikita-bushuev
Copy link

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 👀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants