I would like to load saved image on cache into Image of Jetpack Compose using Coil. I searched in stackoverflow but all suggested ways are for loading web urls. I know that It's possible to convert image file to bitmap and then pass it to Coil but is there any builtin solution for it?
You can use Coil to load any object as a data:
val cacheFile = File(context.cacheDir, "filename")
Image(
rememberImagePainter(cacheFile),
contentDescription = "...",
)
If you've a locally saved image path, you can try the following method,
val painter = rememberImagePainter(data = File(filePath))
Image(
painter = painter,
contentDescription = null)
and to load image from remote url,
val painter = rememberImagePainter(data = imageUrl)
Image(
painter = painter,
contentDescription = null)
For the new version of coil 2.2.2, rememberImagePainter didn't give me good results so I used this-
AsyncImage(
model = ImageRequest.Builder(LocalContext.current)
.data(<file_path>)
.build(),
contentDescription = "icon",
contentScale = ContentScale.Inside,
modifier = Modifier.size(30.dp)
)
Hope it helps someone
Related
I'm using android's photo-picker and then dumping the path into a DB. That all works, but when I try to load the image from RoomDB the image does not load.
I've tried using Image and AsyncImage, but no luck. I've also converted the string to .toUri()
val painter = rememberImagePainter(data = File("content://media/picker/0/com.android.providers.media.photopicker/media/1000000020"))
Image( painter = painter, contentDescription = null)
AsyncImage(model = "content://media/picker/0/com.android.providers.media.photopicker/media/1000000020",
contentDescription = "Image from photo picker",
contentScale = ContentScale.Crop,
modifier = Modifier
.size(100.dp, 100.dp)
)
I have this image I want to load, I am using coil in jetpack compose to try and load it yet it didn't load and just gave me an empty composable. Whenever I try to load a different image from any other website it works, yet when I use the same website I am loading this image from. It doesn't Work.
Here is My Code:
#Composable
fun BookItem(
title: String,
cover: String?,
unreadChapters: Int,
) {
Box(
modifier = Modifier
.wrapContentSize(),
contentAlignment = Alignment.Center
) {
AsyncImage(
model = ImageRequest.Builder(LocalContext.current)
.data(cover)
.crossfade(true)
.build(),
contentDescription = title,
contentScale = ContentScale.Inside,
modifier = Modifier
.clip(RoundedCornerShape(size = 12.dp))
.size(200.dp)
)
}
}
Here is the link:
https://static.lightnovelworld.com/bookcover/300x400/01365-shadow-slave.jpg
I tried using glide instead of coil and I got the same problem.
Thanks and Regards
You can debug it using:
val imageLoader = LocalContext.current.imageLoader.newBuilder()
.logger(DebugLogger())
.build()
AsyncImage(
//...
imageLoader = imageLoader,
)
Result:
🚨 Failed - https://static.lightnovelworld.com/bookcover/300x400/01365-shadow-slave.jpg - coil.network.HttpException: HTTP 403:
You can try to add some headers in you requests using something like:
AsyncImage(
model = ImageRequest.Builder(LocalContext.current)
.data(url)
.setHeader("User-Agent", "Mozilla/5.0")
.build(),
//
)
I'm implementing a simple gallery screen using Jetpack Compose which shows all video and image thumbnails on the screen
I have displayed image from file path successfully. However, I've got trouble in showing video thumbnail. How can I do that using Coil?
Here's my code to show image thumbnails:
#Composable
fun ImageLoaderFromLocal(
url: String,
placeHolderResId: Int,
modifier: Modifier,
transformation: Transformation
) {
val painter = rememberImagePainter(data = File(url),
builder = {
placeholder(placeHolderResId)
crossfade(true)
transformations(transformation)
})
Image(
painter = painter,
contentDescription = null,
modifier = modifier,
contentScale = ContentScale.Inside
)
}
According to Coil documentation, you need to add following dependency:
implementation("io.coil-kt:coil-video:$coil_version")
and specify fetcher in the builder:
val context = LocalContext.current
val painter = rememberImagePainter(
data = url,
builder = {
fetcher(VideoFrameUriFetcher(context))
// optionally set frame location
videoFrameMillis(1000)
placeholder(placeHolderResId)
crossfade(true)
transformations(transformation)
}
)
The other answer doesn't really work any more.
so i tried this one and it worked
val context = LocalContext.current
var visible by rememberSaveable { mutableStateOf(false) }
val imageLoader = ImageLoader.Builder(context)
.components {
add(VideoFrameDecoder.Factory())
}.crossfade(true)
.build()
val painter = rememberAsyncImagePainter(
model = "Your file here",
imageLoader = imageLoader,
The painter should be called in the image composable
like this
Image(
painter = painter,
contentDescription = "",
contentScale = ContentScale.Crop,
alignment = Alignment.Center,
modifier = Modifier.fillMaxSize()
)
i hope this help someone
I am trying to show an image with fill width and auto height using Jetpack Compose Coil. I want the image to take the full width and auto height. But the image only showing when I specify a fixed height.
Image(
painter = rememberImagePainter(
data = post.image
),
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxWidth()
)
I tried with .fillMaxHeight() and .fillMaxSize() but it's not working. Is there any way I could achieve this?
This happens when one of view width/height is calculated as zero, which means it shouldn't be displayed and no need to download it. Check out more about the reasons in this issue on compose tracker.
You should make your size not being equal to zero. Depending you your layout it can be done with variations of width/height/aspect ratio modifiers.
If you'd like to get your image in original size, you can to add size(OriginalSize) to painter builder. This will force image to start loading. This parameter makes your view download and put into the memory full size of the image, without optimizing it for the current view. So use it carefully, only if you're sure the image won't be too big and you really can't add use size modifiers.
Image(
painter = rememberImagePainter(
data = post.image,
builder = {
size(OriginalSize)
},
),
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxWidth()
)
With latest Coil 2.1.0 you can do like this:
val model = ImageRequest.Builder(LocalContext.current)
.data(imageUrl)
.size(Size.ORIGINAL)
.crossfade(true)
.build()
val painter = rememberAsyncImagePainter(model)
Image(
modifier = Modifier.fillMaxWidth(),
painter = painter,
contentDescription = null,
contentScale = ContentScale.FillWidth
)
If your image OriginalSize is to small for your composable you can also use scale(Scale.FIT) in your builder.
Your image will max fit your composable while keeping it's aspect ratio.
Image(
rememberImagePainter(
data = user?.photoUrl?:"",
builder = {
size(OriginalSize)
scale(Scale.FIT)
transformations(CircleCropTransformation())
}
),
contentDescription = "Picture",
contentScale = ContentScale.FillWidth
)
Instead of using size(OriginalSize) that impacts image optimization, you can set min height/width for image (for example 1.dp). This will force image to start loading:
Image(
painter = rememberImagePainter(url),
contentDescription = null,
modifier = Modifier
.fillMaxWidth()
.defaultMinSize(minHeight = 1.dp),
)
I'm working on an Android app using Jetpack Compose 1.0.0 and I'm trying to make a composable that uses a nullable image URL string and, if it's null, it will show a placeholder with painterResource and, if it's not null, it will display the actual image using rememberImagePainter.
The way I was doing that was:
#Composable
fun VariableImagePainterExample (
imageURL: String?
) {
val painter = rememberCoilPainter(
null,
previewPlaceholder = R.drawable.ic_placeholder_user,
fadeIn = true,
)
LaunchedEffect(imageURL) {
painter.request = imageURL
}
Image(painter = painter, contentDescription = null)
}
Unfortunately, the rememberCoilPainter became deprecated from accompanist-coil and it's suggested now to use the rememberImagePainter. However, the ImagePainter.request can't be changed like above. I then tried the following code:
#Composable
fun VariableImagePainterExample (
imageURL: String?
) {
val painter = remember {
mutableStateOf<ImagePainter>(painterResource(id = R.drawable.ic_placeholder_user))
}
LaunchedEffect(imageURL) {
painter.value = rememberImagePainter(imageURL)
}
Image(painter = painter.value, contentDescription = null)
}
But this doesn't work because painterResource and rememberImagePainter must be used on the #Composable function. How can i achieve the same effect as before?
In Coil 2.0.0 both AsyncImage and rememberAsyncImagePainter have placeholder parameter that takes any other painter:
AsyncImage(
model = imageURL,
placeholder = painterResource(R.drawable.placeholder),
contentDescription = null,
)
In Coil 1.4.0 you can use builder like this:
Image(
rememberImagePainter(
imageURL,
builder = {
placeholder(R.drawable.placeholder)
}
),
contentDescription = null,
)
For Coil 2.2.+
It has remeberAsyncImagePainter instead off rememberImagePainter
Image(painter = rememberAsyncImagePainter(model = imageUrl,
imageLoader = ImageLoader.Builder(context).crossfade(true).build()),
contentDescription = "images")