如何从Uri获取Bitmap对象(如果我成功将其存储在
/data/data/MYFOLDER/myimage.png
或file///data/data/MYFOLDER/myimage.png
)在我的申请中使用它?
有没有人知道如何做到这一点?
答案 0 :(得分:507)
这是正确的做法:
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);
查看答案here
答案 1 :(得分:102)
这是正确的做法,同时也要关注内存使用情况:
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(),因此您不会丢失任何功能。
参考文献:
答案 2 :(得分:36)
try
{
Bitmap bitmap = MediaStore.Images.Media.getBitmap(c.getContentResolver() , Uri.parse(paths));
}
catch (Exception e)
{
//handle exception
}
并且是路径必须采用类似这样的格式
file:///mnt/sdcard/filename.jpg
答案 3 :(得分:9)
你可以像这样从uri中检索位图
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
} catch (IOException e) {
e.printStackTrace();
}
答案 4 :(得分:8)
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();
}
}
答案 5 :(得分:7)
这是最简单的解决方案:
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
答案 6 :(得分:7)
Uri imgUri = data.getData();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imgUri);
答案 7 :(得分:3)
似乎在API 29中不推荐使用MediaStore.Images.Media.getBitmap。建议的方法是使用在API 28中添加的ImageDecoder.createSource。
以下是获取位图的方式:
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)
}
答案 8 :(得分:2)
使用如下所示的startActivityForResult metod
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;
}
}
答案 9 :(得分:2)
我尝试了很多方法。完全适合我。
如果从Gallery中选择pictrue。您需要注意要从Uri
或intent.clipdata
获取intent.data
,因为其中一个在不同版本中可能为null。
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 )
}
答案 10 :(得分: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转换为位图。 希望能帮助你。
答案 11 :(得分:1)
现在已描述的getBitmap
的插图我在Kotlin中使用以下方法
PICK_IMAGE_REQUEST ->
data?.data?.let {
val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(it))
imageView.setImageBitmap(bitmap)
}
答案 12 :(得分:1)
InputStream imageStream = null;
try {
imageStream = getContext().getContentResolver().openInputStream(uri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
答案 13 :(得分:1)
private fun setImage(view: ImageView, uri: Uri) {
val stream = contentResolver.openInputStream(uri)
val bitmap = BitmapFactory.decodeStream(stream)
view.setImageBitmap(bitmap)
}
答案 14 :(得分:0)
从移动图库中获取图片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();
}
}
}
答案 15 :(得分:0)
Bitmap imgbitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(),selectedImageUri);
答案 16 :(得分:0)
(科特琳) 因此,截至2020年4月7日,上述所有选项均无效,但这对我有用:
如果要将位图存储在val中并为其设置imageView,请使用以下方法:
val bitmap = BitmapFactory.decodeFile(currentPhotoPath).also { bitmap -> imageView.setImageBitmap(bitmap) }
如果只想将位图设置为和imageView,请使用以下方法:
BitmapFactory.decodeFile(currentPhotoPath).also { bitmap -> imageView.setImageBitmap(bitmap) }
答案 17 :(得分:0)
* 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;
}
答案 18 :(得分:0)
它对我有用
uri uri = data.getData(); 位图 bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
答案 19 :(得分:0)
通过使用 glide 库,您可以从 uri
获取位图,
几乎在三星设备中图像旋转时我们必须使用 exifinterface
但使用滑行不需要检查旋转,图像总是正确接收。
在 kotlin 中你可以得到 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'
答案 20 :(得分:-27)
。 。 重要提示:请参阅下面的@Mark Ingram和@pjv的答案以获得更好的解决方案。 。
你可以试试这个:
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。