Wednesday, March 17, 2021

jetpack compose - Image from URL

MainActivity.kt

package com.cfsuman.jetpackcompose

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.*
import java.io.IOException
import java.lang.Exception
import java.net.URL

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            MainContent()
        }
    }


    @Composable
    fun MainContent(){
        Column(
            modifier = Modifier
                .fillMaxSize()
                .background(Color(0xFF8F9779))
                .padding(16.dp),
            verticalArrangement = Arrangement.spacedBy(16.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
        ) {
            val imageBitmap = remember {
                mutableStateOf<ImageBitmap?>(null)
            }

            // url of image
            val urlImage:URL? =
                try {
                    URL("https://images.pexels.com/photos/4055759/" +
                            "pexels-photo-4055759.jpeg?" +
                            "auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260")
                }catch (e:Exception){
                    null
                }

            // async task to get bitmap from url
            val result: Deferred<Bitmap?> = GlobalScope.async {
                urlImage?.toBitmap()
            }

            imageBitmap.value?.apply {
                Image(
                    bitmap = this,
                    contentDescription = "Localized description",
                    contentScale = ContentScale.Crop,
                    modifier = Modifier
                        .fillMaxWidth()
                        .fillMaxHeight(0.9F)
                        .clip(RoundedCornerShape(16.dp))
                        .border(
                            3.dp,
                            Color(0xFF1B1B1B),
                            RoundedCornerShape(16.dp)
                        )
                )
            }

            GlobalScope.launch(Dispatchers.Main) {
                result.await()?.asImageBitmap()?.apply {
                    try{
                        imageBitmap.value = this
                    }catch (e:Exception){ }
                }
            }
        }
    }


    @Preview
    @Composable
    fun ComposablePreview(){
        //MainContent()
    }

    // extension function to get bitmap from url
    private fun URL.toBitmap(): Bitmap?{
        return try {
            BitmapFactory.decodeStream(openStream())
        }catch (e: IOException){
            null
        }
    }
}