如何从Uri获取位图?

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

有没有人有如何做到这一点的想法?

。 。 重要提示:请参阅下面的@Mark Ingram和@pjv的答案以获得更好的解决scheme。 。 。

你可以试试这个:

 public Bitmap loadBitmap(String url) { Bitmap bm = null; InputStream is = null; BufferedInputStream bis = null; try { URLConnection conn = new URL(url).openConnection(); conn.connect(); is = conn.getInputStream(); bis = new BufferedInputStream(is, 8192); bm = BitmapFactory.decodeStream(bis); } catch (Exception e) { e.printStackTrace(); } finally { if (bis != null) { try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } return bm; } 

但请记住,这个方法只能从一个线程中调用(而不是GUI-thread)。 我是一个AsyncTask。

这是做这件事的正确方法:

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

如果您需要加载非常大的图像,下面的代码将加载到瓷砖中(避免大内存分配):

 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的post中的getBitmap()调用也调用decodeStream(),所以你不会失去任何function。

参考文献:

  • Android:获取SD卡上的图像的缩略图,给出Uri的原始图像

  • 处理大的位图

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

是的path必须是这样的格式

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