android 从图库加载图像并使用Jetpack Compose显示

1l5u6lss  于 2023-06-20  发布在  Android
关注(0)|答案(2)|浏览(225)

嗨,我是Android开发的初学者,我正在努力学习Jetpack Compose,但我面临着一个我无法解决的问题。我有这个代码打开画廊和选择图像

@Composable
fun LoadImage(
    bitmap: MutableState<Bitmap?>
) {
    var imageUri by remember {
        mutableStateOf<Uri?>(null)
    }
    val context = LocalContext.current

    val launcher = rememberLauncherForActivityResult(
        contract =
        ActivityResultContracts.GetContent()
    ) { uri: Uri? ->
        imageUri = uri
    }

    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier
            .fillMaxWidth()
            .padding(6.dp)
    ) {
        Button(onClick = {
            launcher.launch("image/*")
        }) {
            Text(text = "Izaberi sliku")
        }
    }
    Log.d("DEBUG", "IMAGE URI $imageUri")
    imageUri?.let {
        if (Build.VERSION.SDK_INT < 28) {
            bitmap.value = MediaStore.Images
                .Media.getBitmap(context.contentResolver, it)

        } else {
            val source = ImageDecoder
                .createSource(context.contentResolver, it)
            bitmap.value = ImageDecoder.decodeBitmap(source)
        }
    }
}

我从这个组件调用它:

@Composable
fun ShowImage(
    member: Member,
    snackScope: CoroutineScope,
    snackHostState: SnackbarHostState,
) {
    val bitmap = remember {
        mutableStateOf<Bitmap?>(null)
    }

    if (bitmap.value != null) {
        Image(
            painter = rememberAsyncImagePainter(bitmap.value),
            contentDescription = null,
            modifier = Modifier.size(400.dp)
        )
    }

    Row(
        modifier = Modifier
            .padding(12.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        LoadImage(bitmap = bitmap)
    }
    ...

发生了什么:它在Pixel 2 API 28 Emulator中工作得很好,但是当我在LG K22(Android 10)中运行它时,它从Gallery中拾取时不会显示图像。实际上,如果我选择图像,例如/Pictures/Viber文件夹显示,但如果我从任何其他文件夹(例如下载,DCIM)它不显示,它只是白色,而且当我上传该图像到Firebase存储时,它全是黑色的。有人能解释一下发生了什么,我做错了什么吗?实际上,我尝试上传相同的图像,我发现在图像/Viber文件夹从下载目录(复制它,然后从应用程序加载)和它加载。我看到的唯一区别是正确加载的图像大约是200 KB,但没有正确加载的图像大约是3 MB。有没有办法加载和显示图像从画廊在Jetpack合成?我在谷歌上搜索了很多,但没有找到任何解决方案,除了这一个。

6bc51xsx

6bc51xsx1#

如果理解你的问题正确你只是想打开画廊选择一个图像然后要么显示它到屏幕上或上传到firestore.
如果是这样的话,那么为什么你必须做所有的事情呢?你可以使用Coil库中的asyncImage来异步显示你的图像:

var imageUri by remember {
            mutableStateOf<Uri?>(null)
        }    
        val launcher = rememberLauncherForActivityResult(
            contract =
            ActivityResultContracts.GetContent()
        ) { uri: Uri? ->
            imageUri = uri
        }
    AsyncImage(
     model = imageUri,
     contentDescription = null,
     modifier = Modifier
                .padding(4.dp)
                .fillMaxHeight().width(100.dp)
                .clip(RoundedCornerShape(12.dp)),
     contentScale = ContentScale.Crop,
    )
Button(onClick = {
            launcher.launch("image/*")
        }) {
            Text(text = "select image")
        }

现在你可以使用Uri上传图片到Firebase存储。

inb24sb2

inb24sb22#

@JustSightseeing评论引导我找到解决这个问题的方法。我更改了选择图像并将其转换为位图的代码,如下所示:

@Composable
fun LoadImage(
    bitmap: MutableState<Bitmap?>
) {
    val context = LocalContext.current

    var bytes by remember {
        mutableStateOf<ByteArray?>(null)
    }

    val launcher = rememberLauncherForActivityResult(
        contract =
        ActivityResultContracts.GetContent()
    ) { result ->
        val item = context.contentResolver.openInputStream(result!!)
        bytes = item?.readBytes()
        item?.close()
    }

    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier
            .fillMaxWidth()
            .padding(6.dp)
    ) {
        Button(onClick = {
            launcher.launch("image/*")
        }) {
            Text(text = "Izaberi sliku")
        }
    }

    bytes?.let {
        val bos = ByteArrayOutputStream()
        val bmp = BitmapFactory.decodeByteArray(it, 0, it.size).compress(Bitmap.CompressFormat.JPEG, 50, bos)
        bitmap.value = BitmapFactory.decodeByteArray(bos.toByteArray(), 0, bos.toByteArray().size)
    }

}

谢谢

相关问题