Kamel-Media / Kamel

Kotlin asynchronous media loading and caching library for Compose.
Apache License 2.0
595 stars 23 forks source link

null cannot be cast to non-null type android.graphics.Bitmap #48

Closed TareHimself closed 10 months ago

TareHimself commented 1 year ago
java.lang.NullPointerException: null cannot be cast to non-null type android.graphics.Bitmap
    at io.kamel.image.decoder.ImageBitmapDecoder.decode(AndroidImageBitmapDecoder.kt:21)
    at io.kamel.image.decoder.ImageBitmapDecoder$decode$1.invokeSuspend(Unknown Source:15)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115)
    at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:100)
    at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)

This is the image

@file:Suppress("INLINE_FROM_HIGHER_PLATFORM")
package com.tarehimself.mangaz.ui.screens.search

import androidx.compose.foundation.Image
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.unit.dp
import com.tarehimself.mangaz.getPlatform
import io.kamel.core.Resource
import io.kamel.image.asyncPainterResource

@Composable
fun SearchResult(data: String) {
    Surface(
        modifier = Modifier.height(300.dp).border(
            width = 2.dp,
            color = Color.Transparent,
            shape = RoundedCornerShape(5.dp)
        ).padding(horizontal = 5.dp, vertical = 5.dp),
        color = Color.Transparent,
    ) {
        when (val resource = asyncPainterResource("https://www.example.com/image.jpg")) {
            is Resource.Loading -> {
                Text("Loading...")
            }
            is Resource.Success -> {
                val painter: Painter = resource.value
                Image(painter= painter, contentDescription = "Profile",modifier = Modifier.fillMaxSize())
            }
            is Resource.Failure -> {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = Color.Red,
                ){
                    TextField(value = resource.exception.stackTraceToString(), onValueChange = {})
                }
            }
        }
    }
}

And this is the config

@Composable
fun App(){
    val kamelConfig = KamelConfig {
        takeFrom(KamelConfig.Default)
    }

    CompositionLocalProvider(LocalKamelConfig provides kamelConfig) {
        Surface(
            modifier = Modifier.fillMaxSize(),
            color = MaterialTheme.colors.background,

            ) {
            SearchScreen()
        }
    }
}

The error is happening on android

7va commented 7 months ago

Same issue with 0.9.0

TareHimself commented 7 months ago

Frankly I gave up and went with my own image loader , it's not all that complicated once you get into it

TareHimself commented 7 months ago

I can link my repo if you want to see how it was implemented

luca992 commented 7 months ago

An error with that example is expected. as that link you are loading is not an image.

Anyways. I just pushed a commit that makes BitmapDecoder errors more descriptive.

Your example will now return on failure:

java.lang.IllegalArgumentException: Failed to decode 1256 bytes to a bitmap. Decoded bytes:
<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">
    body {
        background-color: #f0f0f2;
        margin: 0;
        padding: 0;
        font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;

    }
    div {
        width: 600px;
        margin: 5em auto;
        padding: 2em;
        background-color: #fdfdff;
        border-radius: 0.5em;
        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
    }
    a:link, a:visited {
        color: #38488f;
        text-decoration: none;
    }
    @media (max-width: 700px) {
        div {
            margin: 0 auto;
            width: auto;
        }
    }
    </style>    
</head>

<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is for use in illustrative examples in documents. You may use this
    domain in literature without prior coordination or asking for permission.</p>
    <p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>

    at io.kamel.image.decoder.ImageBitmapDecoder.decode(DesktopImageBitmapDecoder.kt:27)
    at io.kamel.core.ImageLoadingKt$loadImageBitmapResource$$inlined$loadResource$1$1$2.emit(Emitters.kt:228)
    at kotlinx.coroutines.flow.FlowKt__ChannelsKt.emitAllImpl$FlowKt__ChannelsKt(Channels.kt:37)
    at kotlinx.coroutines.flow.FlowKt__ChannelsKt.access$emitAllImpl$FlowKt__ChannelsKt(Channels.kt:1)
    at kotlinx.coroutines.flow.FlowKt__ChannelsKt$emitAllImpl$1.invokeSuspend(Channels.kt)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
    at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115)
    at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:103)
    at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)
TareHimself commented 7 months ago

Oh , how did I not notice at the time . Thanks

7va commented 7 months ago

Yeah, my bad too. Sorry and tnx!