如何从 Api 级别 30 中的 imageUri 获取位图?

How to get Bitmap From imageUri in Api level 30?

我在旧版本中使用 getBitmap 方法,但我找不到 getBitmap From Uri 的任何替代方法。

        try {
            bitmap = MediaStore.Images.Media.getBitmap(contentResolver, imageUri);
        } catch (IOException e) {
            e.printStackTrace();
        }

现在我从 android 指南中找到了另一种方法,但仍然无效。 我不知道如何在工作线程中执行此方法。 指南说此方法应该 运行 在工作线程中。谁能帮我解决这个问题?

        try {
            bitmap = ImageDecoder.decodeBitmap(ImageDecoder.createSource(contentResolver, imageUri));
        } catch (IOException e) {
            e.printStackTrace();
        }

我创建了简单的 class 来从 imageUri 获取位图。 在这里。

public class BitmapResolver {


    @SuppressWarnings("deprecation")
    private static Bitmap getBitmapLegacy(@NonNull ContentResolver contentResolver, @NonNull Uri fileUri){
        Bitmap bitmap = null;

        try {
            bitmap = MediaStore.Images.Media.getBitmap(contentResolver, fileUri);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return bitmap;
    }

    @TargetApi(Build.VERSION_CODES.P)
    private static Bitmap getBitmapImageDecoder(@NonNull ContentResolver contentResolver, @NonNull Uri fileUri){
        Bitmap bitmap = null;

        try {
            bitmap = ImageDecoder.decodeBitmap(ImageDecoder.createSource(contentResolver, fileUri));
        } catch (IOException e) {
            e.printStackTrace();
        }

        return bitmap;
    }

    public static Bitmap getBitmap(@NonNull ContentResolver contentResolver, Uri fileUri){
        if (fileUri == null){
            return null;
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P){
            return getBitmapImageDecoder(contentResolver, fileUri);
        } else{
            return getBitmapLegacy(contentResolver, fileUri);
        }
    }
}

看看 documentation

This method was deprecated in API level 29. loading of images should be performed through ImageDecoder#createSource(ContentResolver, Uri), which offers modern features like PostProcessor.

所以你必须使用 ImageDecoder.createSource,像这样:

Bitmap bitmap = null;
ContentResolver contentResolver = getContentResolver(); 
try {
    if(Build.VERSION.SDK_INT < 28) {
        bitmap = MediaStore.Images.Media.getBitmap(contentResolver, imageUri);
    } else {
        ImageDecoder.Source source = ImageDecoder.createSource(contentResolver, imageUri);
        bitmap = ImageDecoder.decodeBitmap(source);
    }
} catch (Exception e) {
    e.printStackTrace();
}

以上应该是线程安全的。

这里是 Kotlin 开发人员

fun getBitmap(contentResolver: ContentResolver, fileUri: Uri?): Bitmap? {
    return try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            ImageDecoder.decodeBitmap(ImageDecoder.createSource(contentResolver, fileUri!!))
        } else {
            MediaStore.Images.Media.getBitmap(contentResolver, fileUri)
        }
    } catch (e: Exception){
        null
    }
}