如何从Uri中获得位图对象(如果我成功地将它存储在 /data/data/MYFOLDER/myimage.png或file///data/data/MYFOLDER/myimage.png)在我的应用程序中使用它?< / p >
/data/data/MYFOLDER/myimage.png
file///data/data/MYFOLDER/myimage.png
有人知道怎么做到吗?
下面是正确的做法:
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(),因此不会丢失任何功能。
引用:
Android:获取SD卡上图像的缩略图,给定原始图像的Uri
处理大位图
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.getBitmap在API 29中已弃用。推荐的方法是使用ImageDecoder.createSource,它是在API 28中添加的。
MediaStore.Images.Media.getBitmap
API 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不读取
ImageDecoder.decodeBitmap
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);
val bitmap = BitmapFactory.decodeFile(currentPhotoPath).also { bitmap -> imageView.setImageBitmap(bitmap) } < / p >
val bitmap = BitmapFactory.decodeFile(currentPhotoPath).also { bitmap -> imageView.setImageBitmap(bitmap) }
BitmapFactory.decodeFile(currentPhotoPath).also { bitmap -> imageView.setImageBitmap(bitmap) } < / p >
BitmapFactory.decodeFile(currentPhotoPath).also { bitmap -> imageView.setImageBitmap(bitmap) }
我已经尝试了很多方法。这对我来说非常合适。
如果你从图库中选择图片。你需要注意从intent.clipdata或intent.data获取Uri,因为其中一个在不同的版本中可能为空。
intent.clipdata
intent.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获得位图,
uri
几乎在三星设备图像旋转时,我们必须使用exifinterface检查旋转
exifinterface
但使用滑动不需要检查旋转,图像总是正确接收。
在kotlin中,你可以得到bitmap as
bitmap
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(); }