如何从Uri获取Bitmap?

268

如何从Uri获取Bitmap对象(如果我成功将其存储在/data/data/MYFOLDER/myimage.pngfile///data/data/MYFOLDER/myimage.png中),以便在我的应用程序中使用?

有没有人有实现这个的想法?

24个回答

4
通过使用Glide库,您可以从URI获取位图。
在三星设备上,图片可能会旋转,需要使用ExifInterface检查旋转角度;但是使用Glide时,无需检查旋转,图像始终正确接收。
在Kotlin中,您可以使用以下代码获取位图:
CoroutineScope(Dispatchers.IO).launch {
   var bitmap = Glide.with(context).asBitmap().load(imageUri).submit().get()//this is synchronous approach                  
}

我正在使用这个依赖

api 'com.github.bumptech.glide:glide:4.12.0'
kapt 'com.github.bumptech.glide:compiler:4.12.0'

3
ContentResolver cr = context.getContentResolver();
try (InputStream input = cr.openInputStream(url)) {
    Bitmap bitmap = BitmapFactory.decodeStream(input);
}

2
请考虑稍微解释一下你的答案,特别是 cr(contentResolver)部分。 - Ajith Gopi

3

现在getBitmap已经被弃用,我使用以下Kotlin方法进行替代:

PICK_IMAGE_REQUEST ->
    data?.data?.let {
        val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(it))
        imageView.setImageBitmap(bitmap)
    }

3
  InputStream imageStream = null;
    try {
        imageStream = getContext().getContentResolver().openInputStream(uri);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);

2
请使用以下方式调用startActivityForResult方法。
        startActivityForResult(new Intent(Intent.ACTION_PICK).setType("image/*"), PICK_IMAGE);

你可以得到如下结果:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode != RESULT_OK) {
        return;
    }
    switch (requestCode) {
        case PICK_IMAGE:
            Uri imageUri = data.getData();
            try {
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
            } catch (IOException e) {
                e.printStackTrace();
            }
         break;
    }
}

2
val bitmap = context.contentResolver.openInputStream(uri).use { data ->
        BitmapFactory.decodeStream(data)
    }

您需要使用 use 打开输入流,因为它会在操作完成后自动关闭流。


2
我没有看到正确答案,所以我会在这里安装这个扩展。
fun Context.getBitmap(uri: Uri): Bitmap =
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) ImageDecoder.decodeBitmap(ImageDecoder.createSource(this.contentResolver, uri))
    else MediaStore.Images.Media.getBitmap(this.contentResolver, uri)

代码示例:

val bitmap = context.getBitmap(uri)

提示:您也可以更新用于活动/片段的扩展,这样您就无需编写上下文了。更多合成糖)

2

我尝试了很多方法,这个对我非常有效。

如果您从相册选择图片。您需要注意从intent.clipdataintent.data获取Uri,因为它们中的一个在不同版本中可能为空。

  private fun onChoosePicture(data: Intent?):Bitmap {
        data?.let {
            var fileUri:Uri? = null

              data.clipData?.let {clip->
                  if(clip.itemCount>0){
                      fileUri = clip.getItemAt(0).uri
                  }
              }
            it.data?.let {uri->
                fileUri = uri
            }


               return MediaStore.Images.Media.getBitmap(this.contentResolver, fileUri )
}

1
你可以使用这个结构:
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
    super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
    switch(requestCode) {
        case 0:
            if(resultCode == RESULT_OK){
                    Uri selectedImage = imageReturnedIntent.getData();
                    Bundle extras = imageReturnedIntent.getExtras();
                    bitmap = extras.getParcelable("data");
            }
            break;
   }

通过这个方法,您可以轻松地将URI转换为位图。希望能对您有所帮助。

1
这在Android Nougat 7.1.1版本中无法工作。这个extras.getParcelable("data");返回null。 - Developer_vaibhav

1

(KOTLIN) 截至2020年4月7日,上述提到的选项都无法使用,但以下方法适用:

  1. 如果您想将位图存储在val中并将其设置为imageView,请使用以下代码:

    val bitmap = BitmapFactory.decodeFile(currentPhotoPath).also { bitmap -> imageView.setImageBitmap(bitmap) }

  2. 如果您只想将位图设置为imageView,请使用以下代码:

    BitmapFactory.decodeFile(currentPhotoPath).also { bitmap -> imageView.setImageBitmap(bitmap) }


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接