I have hundreds of png files in assets folder and I want to load them into Image composable. But what I can use only images in drawable folder.
how to load images from assets into Image?
Example:
var bitmapState by remember{ mutableStateOf<Bitmap?>(null) }
val context = LocalContext.current
LaunchedEffect(Unit) {
bitmapState = BitmapFactory.decodeStream(context.assets.open("assetsImage.png"))
}
if (null != bitmapState) {
val bitmap = bitmapState!!.asImageBitmap()
Image(
bitmap = bitmap,
"assetsImage",
modifier = Modifier.fillMaxSize(),
colorFilter = null
)
}
#Halifax solution works but I have some performance issue with it. by using Coil it is much smoother and cleaner.
in build.gradle (:app) :
implementation("io.coil-kt:coil-compose:2.2.2")
and then:
AsyncImage(
model = "file:///android_asset/images_folder/image.png",
contentDescription = "",
)
Related
I have tried below code but it reflects nothing in the UI, I'm missing anything here?
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
loadUi()
}
}
#Composable
fun loadUi() {
CraneWrapper {
MaterialTheme {
Image(
(ResourcesCompat.getDrawable(
resources,
R.mipmap.ic_launcher,
null
) as BitmapDrawable).bitmap
)
}
}
}
}
You can use the painterResource function:
Image(painterResource(R.drawable.ic_xxxx),"content description")
The resources with the given id must point to either fully rasterized images (ex. PNG or JPG files) or VectorDrawable xml assets.
It means that this method can load either an instance of BitmapPainter or VectorPainter for ImageBitmap based assets or vector based assets respectively.
Example:
Card(
modifier = Modifier.size(48.dp).tag("circle"),
shape = CircleShape,
elevation = 2.dp
) {
Image(
painterResource(R.drawable.ic_xxxx),
contentDescription = "",
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize()
)
}
Starting at version 1.0.0-beta01:
Image(
painter = painterResource(R.drawable.your_drawable),
contentDescription = "Content description for visually impaired"
)
As imageResourceis not available anymore, the solutions with painterResource are indeed correct, e.g.
Image(painter = painterResource(R.drawable.ic_heart), contentDescription = "content description")
But you can actually still use Bitmap instead of drawable if you need so:
Image(bitmap = bitmap.asImageBitmap())
.asImageBitmap() is an extensions on Bitmap that compose provides and it creates an ImageBitmap from the given Bitmap.
Working in 0.1.0-dev14
Loading drawable in Image could be achieve from this:
Image(
imageResource(id = R.drawable.scene_01),
modifier = Modifier.preferredHeightIn(160.dp, 260.dp)
.fillMaxWidth(),
contentScale = ContentScale.Crop
)
Now, I'm trying to upload drawable in Circle Image that sounds tricky but too easy in JetPack Compose. You can do achieve in this way:
Image(
asset = imageResource(id = R.drawable.scene_01),
modifier = Modifier.drawBackground(
color = Color.Black,
style = Stroke(4f),
shape = CircleShape
).preferredSize(120.dp)
.gravity(Alignment.CenterHorizontally)
.clip(CircleShape),
contentScale = ContentScale.FillHeight
)
Output:
Try This one but if you copy the code and then paste it I don't know why but it won't work so just type it as it is and replace the image id
Image(
painter = painterResource(id = R.drawable.tanjim),
contentDescription = null,
)
version=1.0.0-beta01,use painterResource,imageResource has been deleted.
example
Image(
painterResource(R.drawable.ic_vector_or_png),
contentDescription = null,
modifier = Modifier.requiredSize(50.dp)
)
android developer doc
With version 1.0.0-beta01
It's like below
Image(
painter = painterResource(R.drawable.header),
contentDescription = null,
)
I found that there is a function imageFromResource() in AndroidImage.kt:
fun imageFromResource(res: Resources, resId: Int): Image {
return AndroidImage(BitmapFactory.decodeResource(res, resId))
}
so your code would be:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
loadUi()
}
}
#Composable
fun loadUi() {
CraneWrapper {
MaterialTheme {
val image = imageFromResource(resources, R.mipmap.ic_launcher)
SimpleImage(image)
}
}
}
}
#Composable
fun loadUi() {
val image = +imageResource(R.drawable.header)
CraneWrapper {
MaterialTheme {
Container(expanded = true,height = 180.dp) {
//Use the Clip() function to round the corners of the image
Clip(shape = RoundedCornerShape(8.dp)) {
//call DrawImage() to add the graphic to the app
DrawImage(image)
}
}
}
}
}
I found SimpleImage class from jetpack compose library to load the image but this is a temporary solution, and I didn't find any styling option with this yet.
// TODO(Andrey) Temporary. Should be replaced with our proper Image component when it available
#Composable
fun SimpleImage(
image: Image
) {
// TODO b132071873: WithDensity should be able to use the DSL syntax
WithDensity(block = {
Container(width = image.width.toDp(), height = image.height.toDp()) {
Draw { canvas, _ ->
canvas.drawImage(image, Offset.zero, Paint())
}
}
})
}
I have used it in this way
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
loadUi()
}
}
#Composable
fun loadUi() {
CraneWrapper {
MaterialTheme {
val bitmap = (ResourcesCompat.getDrawable(
resources,
R.mipmap.ic_launcher,
null
) as BitmapDrawable).bitmap
SimpleImage(Image(bitmap))
}
}
}
}
Still, I'm not sure this is the correct way of loading image from drawables.
Google updated their API. For 0.1.0-dev03 loading images is synchronous and is done this way
val icon = +imageResource(R.drawable.ic_xxx)
To draw the image
Container(modifier = Height(100.dp) wraps Expanded) {
DrawImage(icon)
}
Currently the above code relies on you specifying either the exact height or width. It seems that scaling the image is not supported if you want for example 100 dp height and wrap_content instead of Expanded which expands the full width.
Does any one know how to solve this issue? Also is possible to fit the image inside it's container like old way scaleType=fitCenter?
compose.animation:animation-graphics API will certainly be removed and so I want to know what is the best way to use animated vector drawable with JetPack Compose?
Here is the ancient code of using the API:
val image = animatedVectorResource(drawableId)
var atEnd by remember { mutableStateOf(false) }
Image(
painter = image.painterFor(atEnd),
contentDescription = "Your content description",
modifier = Modifier.size(64.dp).clickable {
atEnd = !atEnd
}
)
From android docs:
Note: This API is transient and will be likely removed for encouraging async resource loading.
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
With painter it's possible to draw on ImageBitmap with the snippet
val imageBitmap: ImageBitmap = imageResource(id = R.drawable.landscape3)
val customPainter = remember {
object : Painter() {
override val intrinsicSize: Size
get() = Size(imageBitmap.width.toFloat(), imageBitmap.height.toFloat())
override fun DrawScope.onDraw() {
drawImage(imageBitmap)
drawLine(
color = Color.Red,
start = Offset(0f, 0f),
end = Offset(imageBitmap.width.toFloat(), imageBitmap.height.toFloat()),
strokeWidth = 5f
)
}
}
}
Image(painter = customPainter, contentDescription = null)
loadFontResource is deprecated. Use fontResource instead.
imageResource, loadImageResource, vectorResource, and
loadVectorResource are deprecated. Use painterResource instead.
(I6b809)
with alpha12 imageResource is deprecated. painter's drawImage(imageBitmap) function that draws image has no replacement or another function other than the one takes imageBitmap as parameter?
What's the point of ImageBitmap as of alpha12 since there is no not deprecated function to create it with a resource, and function to get ImageBitmap from Painter does not exist.
starting from Compose UI 1.0.0-beta01
imageResource and vectorResource are now extension functions on ImageBitmap and ImageVector companions respectively. load{Image,Vector,Font}Resource functions have been deleted. (I89130)
import androidx.compose.ui.res.imageResource
// ...
val imageBitmap: ImageBitmap = ImageBitmap.imageResource(R.drawable.landscape3)
painterResource under the hood calls imageFromResource, so we can use it too:
val imageBitmap: ImageBitmap = imageFromResource(
LocalContext.current.resources,
R.drawable.landscape3
)
if you need set ImageVector from drawable folder use:
ImageVector.vectorResource(id = R.drawable.ic_example)
ic_example is vector ".xml" file added from svg file
I use this method to use bitmap or SVG
Image(
painterResource(id = R.drawable.video),
contentDescription = "",
)
with Compose 1.0 stable and above, you should use
useResource("image.png") { loadImageBitmap(it) }
this will return a ImageBitmap object.
There is also painterResource("image.png") but this will return a Painter object.
I have tried below code but it reflects nothing in the UI, I'm missing anything here?
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
loadUi()
}
}
#Composable
fun loadUi() {
CraneWrapper {
MaterialTheme {
Image(
(ResourcesCompat.getDrawable(
resources,
R.mipmap.ic_launcher,
null
) as BitmapDrawable).bitmap
)
}
}
}
}
You can use the painterResource function:
Image(painterResource(R.drawable.ic_xxxx),"content description")
The resources with the given id must point to either fully rasterized images (ex. PNG or JPG files) or VectorDrawable xml assets.
It means that this method can load either an instance of BitmapPainter or VectorPainter for ImageBitmap based assets or vector based assets respectively.
Example:
Card(
modifier = Modifier.size(48.dp).tag("circle"),
shape = CircleShape,
elevation = 2.dp
) {
Image(
painterResource(R.drawable.ic_xxxx),
contentDescription = "",
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize()
)
}
Starting at version 1.0.0-beta01:
Image(
painter = painterResource(R.drawable.your_drawable),
contentDescription = "Content description for visually impaired"
)
As imageResourceis not available anymore, the solutions with painterResource are indeed correct, e.g.
Image(painter = painterResource(R.drawable.ic_heart), contentDescription = "content description")
But you can actually still use Bitmap instead of drawable if you need so:
Image(bitmap = bitmap.asImageBitmap())
.asImageBitmap() is an extensions on Bitmap that compose provides and it creates an ImageBitmap from the given Bitmap.
Working in 0.1.0-dev14
Loading drawable in Image could be achieve from this:
Image(
imageResource(id = R.drawable.scene_01),
modifier = Modifier.preferredHeightIn(160.dp, 260.dp)
.fillMaxWidth(),
contentScale = ContentScale.Crop
)
Now, I'm trying to upload drawable in Circle Image that sounds tricky but too easy in JetPack Compose. You can do achieve in this way:
Image(
asset = imageResource(id = R.drawable.scene_01),
modifier = Modifier.drawBackground(
color = Color.Black,
style = Stroke(4f),
shape = CircleShape
).preferredSize(120.dp)
.gravity(Alignment.CenterHorizontally)
.clip(CircleShape),
contentScale = ContentScale.FillHeight
)
Output:
Try This one but if you copy the code and then paste it I don't know why but it won't work so just type it as it is and replace the image id
Image(
painter = painterResource(id = R.drawable.tanjim),
contentDescription = null,
)
version=1.0.0-beta01,use painterResource,imageResource has been deleted.
example
Image(
painterResource(R.drawable.ic_vector_or_png),
contentDescription = null,
modifier = Modifier.requiredSize(50.dp)
)
android developer doc
With version 1.0.0-beta01
It's like below
Image(
painter = painterResource(R.drawable.header),
contentDescription = null,
)
I found that there is a function imageFromResource() in AndroidImage.kt:
fun imageFromResource(res: Resources, resId: Int): Image {
return AndroidImage(BitmapFactory.decodeResource(res, resId))
}
so your code would be:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
loadUi()
}
}
#Composable
fun loadUi() {
CraneWrapper {
MaterialTheme {
val image = imageFromResource(resources, R.mipmap.ic_launcher)
SimpleImage(image)
}
}
}
}
#Composable
fun loadUi() {
val image = +imageResource(R.drawable.header)
CraneWrapper {
MaterialTheme {
Container(expanded = true,height = 180.dp) {
//Use the Clip() function to round the corners of the image
Clip(shape = RoundedCornerShape(8.dp)) {
//call DrawImage() to add the graphic to the app
DrawImage(image)
}
}
}
}
}
I found SimpleImage class from jetpack compose library to load the image but this is a temporary solution, and I didn't find any styling option with this yet.
// TODO(Andrey) Temporary. Should be replaced with our proper Image component when it available
#Composable
fun SimpleImage(
image: Image
) {
// TODO b132071873: WithDensity should be able to use the DSL syntax
WithDensity(block = {
Container(width = image.width.toDp(), height = image.height.toDp()) {
Draw { canvas, _ ->
canvas.drawImage(image, Offset.zero, Paint())
}
}
})
}
I have used it in this way
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
loadUi()
}
}
#Composable
fun loadUi() {
CraneWrapper {
MaterialTheme {
val bitmap = (ResourcesCompat.getDrawable(
resources,
R.mipmap.ic_launcher,
null
) as BitmapDrawable).bitmap
SimpleImage(Image(bitmap))
}
}
}
}
Still, I'm not sure this is the correct way of loading image from drawables.
Google updated their API. For 0.1.0-dev03 loading images is synchronous and is done this way
val icon = +imageResource(R.drawable.ic_xxx)
To draw the image
Container(modifier = Height(100.dp) wraps Expanded) {
DrawImage(icon)
}
Currently the above code relies on you specifying either the exact height or width. It seems that scaling the image is not supported if you want for example 100 dp height and wrap_content instead of Expanded which expands the full width.
Does any one know how to solve this issue? Also is possible to fit the image inside it's container like old way scaleType=fitCenter?