如何从Uri获得位图?

如何从Uri中获得位图对象(如果我成功地将它存储在 /data/data/MYFOLDER/myimage.pngfile///data/data/MYFOLDER/myimage.png)在我的应用程序中使用它?< / p >

有人知道怎么做到吗?

437568 次浏览

下面是正确的做法:

protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK)
{
Uri imageUri = data.getData();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
}
}

如果你需要加载非常大的图像,下面的代码将以tile的形式加载它(避免大的内存分配):

BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(myStream, false);
Bitmap region = decoder.decodeRegion(new Rect(10, 10, 50, 50), null);

参见答案在这里

下面是正确的方法,同时也要注意内存的使用情况:

protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK)
{
Uri imageUri = data.getData();
Bitmap bitmap = getThumbnail(imageUri);
}
}


public static Bitmap getThumbnail(Uri uri) throws FileNotFoundException, IOException{
InputStream input = this.getContentResolver().openInputStream(uri);


BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
onlyBoundsOptions.inJustDecodeBounds = true;
onlyBoundsOptions.inDither=true;//optional
onlyBoundsOptions.inPreferredConfig=Bitmap.Config.ARGB_8888;//optional
BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
input.close();


if ((onlyBoundsOptions.outWidth == -1) || (onlyBoundsOptions.outHeight == -1)) {
return null;
}


int originalSize = (onlyBoundsOptions.outHeight > onlyBoundsOptions.outWidth) ? onlyBoundsOptions.outHeight : onlyBoundsOptions.outWidth;


double ratio = (originalSize > THUMBNAIL_SIZE) ? (originalSize / THUMBNAIL_SIZE) : 1.0;


BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inSampleSize = getPowerOfTwoForSampleRatio(ratio);
bitmapOptions.inDither = true; //optional
bitmapOptions.inPreferredConfig=Bitmap.Config.ARGB_8888;//
input = this.getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
input.close();
return bitmap;
}


private static int getPowerOfTwoForSampleRatio(double ratio){
int k = Integer.highestOneBit((int)Math.floor(ratio));
if(k==0) return 1;
else return k;
}

Mark Ingram的文章中的getBitmap()调用也调用decodeStream(),因此不会丢失任何功能。

引用:

try
{
Bitmap bitmap = MediaStore.Images.Media.getBitmap(c.getContentResolver() , Uri.parse(paths));
}
catch (Exception e)
{
//handle exception
}

yes路径必须是这样的格式

file:///mnt/sdcard/filename.jpg

private void uriToBitmap(Uri selectedFileUri) {
try {
ParcelFileDescriptor parcelFileDescriptor =
getContentResolver().openFileDescriptor(selectedFileUri, "r");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);


parcelFileDescriptor.close();
} catch (IOException e) {
e.printStackTrace();
}
}

你可以这样做:

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转换为位图。

使用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;
}
}

从移动库中获取图像uri的完整方法。

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);


if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri filePath = data.getData();


try { //Getting the Bitmap from Gallery
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
rbitmap = getResizedBitmap(bitmap, 250);//Setting the Bitmap to ImageView
serImage = getStringImage(rbitmap);
imageViewUserImage.setImageBitmap(rbitmap);
} catch (IOException e) {
e.printStackTrace();
}




}
}

你可以像这样从uri中检索位图

Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
} catch (IOException e) {
e.printStackTrace();
}

这是最简单的解决方案:

Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
Uri imgUri = data.getData();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imgUri);

似乎MediaStore.Images.Media.getBitmapAPI 29中已弃用。推荐的方法是使用ImageDecoder.createSource,它是在API 28中添加的。

下面是如何获得位图:

val bitmap = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
ImageDecoder.decodeBitmap(ImageDecoder.createSource(requireContext().contentResolver, imageUri))
} else {
MediaStore.Images.Media.getBitmap(requireContext().contentResolver, imageUri)
}

重要:ImageDecoder.decodeBitmap读取EXIF方向,Media.getBitmap不读取

现在我在Kotlin中使用以下方法

PICK_IMAGE_REQUEST ->
data?.data?.let {
val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(it))
imageView.setImageBitmap(bitmap)
}
  InputStream imageStream = null;
try {
imageStream = getContext().getContentResolver().openInputStream(uri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
< p >(芬兰湾的科特林) 所以,截至2020年4月7日,上面提到的选项都没用,但下面的选项对我有用:

  1. 如果你想在val中存储位图,并设置一个imageView,使用这个:

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

  2. 如果你只是想设置位图为和imageView,使用这个:

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

我已经尝试了很多方法。这对我来说非常合适。

如果你从图库中选择图片。你需要注意从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 )
}
private fun setImage(view: ImageView, uri: Uri) {
val stream = contentResolver.openInputStream(uri)
val bitmap = BitmapFactory.decodeStream(stream)
view.setImageBitmap(bitmap)
}
* For getting bitmap from uri. Work for me perfectly.
    

    

public static Bitmap decodeUriToBitmap(Context mContext, Uri sendUri) {
Bitmap getBitmap = null;
try {
InputStream image_stream;
try {
image_stream = mContext.getContentResolver().openInputStream(sendUri);
getBitmap = BitmapFactory.decodeStream(image_stream);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return getBitmap;
}

通过使用glide库,你可以从uri获得位图,

几乎在三星设备图像旋转时,我们必须使用exifinterface检查旋转

但使用滑动不需要检查旋转,图像总是正确接收。

在kotlin中,你可以得到bitmap as

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'
ContentResolver cr = context.getContentResolver();
try (InputStream input = cr.openInputStream(url)) {
Bitmap bitmap = BitmapFactory.decodeStream(input);
}

在2022年使用线圈库。

< a href = " https://coil-kt.github。Io /coil/compose/" rel="nofollow noreferrer">https://coil-kt.github.io/coil/compose/

对于喷气背包组合

            AsyncImage(
model = uriOfImage,
contentDescription = null,
)

我没有看到正确答案,所以我把这个扩展写在这里

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)
提示:你也可以更新活动/片段的扩展,所以你不需要 根本不需要写上下文。多一点合成糖)

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();
}