coil: [Coil 3] Local image files don't show on PC

Describe the bug Hello! Local image files don’t show on PC. Error type is not in the function error()

To Reproduce

val platformContext = LocalPlatformContext.current

val uri = "file:///H:/1.png".toUri()

val request = ImageRequest.Builder(platformContext)
    .data(uri)
    .error {
        println("error")
        null
    }.build()

AsyncImage(
    model = request,
    contentDescription = "",
    contentScale = ContentScale.FillHeight,
    modifier = Modifier.fillMaxSize()
)

Logs/Screenshots image

image

image

Version Coil 3.0.0-alpha01

kotlin.version=1.9.21 agp.version=8.1.4 compose.version=1.5.11

About this issue

  • Original URL
  • State: open
  • Created 6 months ago
  • Comments: 24 (2 by maintainers)

Most upvoted comments

Possible workaround to use normal windows path.

Create a custom fetcher:

internal class WindowsFileUriFetcher(
        private val uri: Uri,
        private val options: Options,
) : Fetcher {

    @OptIn(InternalCoilApi::class)
    override suspend fun fetch(): FetchResult {
        val path = uri.toString().toPath()
        return SourceFetchResult(
                source = ImageSource(path, options.fileSystem),
                mimeType = MimeTypeMap.getMimeTypeFromExtension(path.name.substringAfterLast('.', "")),
                dataSource = DataSource.DISK,
        )
    }

    class Factory : Fetcher.Factory<Uri> {

        private val regex = "^[a-zA-Z]:\\\\.*".toRegex()

        override fun create(
                data: Uri,
                options: Options,
                imageLoader: ImageLoader,
        ): Fetcher? {
            if (hostOs != OS.Windows || !regex.matches(data.toString())) return null
            return WindowsFileUriFetcher(data, options)
        }
    }
}

Register it:

ImageLoader.Builder(context)
            .components {
                add(OkHttpNetworkFetcherFactory())
                add(WindowsFileUriFetcher.Factory())
            }
            .build()

This workaround is fine in my Windows, but I suppose it will break anywhere else.

val loc = "file://" + imageFile.absolutePath.replace("\\", "/")

Would you mind posting the exact contents of the String that you passed to AsyncImage? My images are located in C:…\AppData\ and I tried all possibilities with \ and / and nothing would work for me…

Of course, this is the original file: .myapp\190f6e6c-e527-456a-84bc-301a62bf5486.png (I’ve tried passing both the File and its path as a String) and the workaround is using the String file://.myapp/190f6e6c-e527-456a-84bc-301a62bf5486.png instead.

Thank you. What exactly is .myapp? Is it the root directory of your app? I was looking for a workaround where I can load images from the “AppData” folder on the C: drive. Any ideas? Because using the absolute path with the drive letter seems to create the confusion within Coil.

It’s just a subfolder of the working directory of my app, nothing special.