我可以从android中的uri获取图像文件的宽度和高度吗?
Posted
技术标签:
【中文标题】我可以从android中的uri获取图像文件的宽度和高度吗?【英文标题】:can i get image file width and height from uri in android? 【发布时间】:2013-05-02 16:40:09 【问题描述】:我可以通过MediaStore.Images.Media
正常获取图片宽度
但我需要从从 dropbox 中选择的图像中获取图像的宽度和高度
所以目前我有以下方法从保管箱获取图像大小
private void getDropboxIMGSize(Uri uri)
String size = Long.toString(new File(uri.getPath()).length());
return size;
但我真正需要的是获取文件的宽度和高度值
有人知道如何实现吗?请帮忙!
【问题讨论】:
【参考方案1】:private void getDropboxIMGSize(Uri uri)
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(new File(uri.getPath()).getAbsolutePath(), options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
不,没有办法。您必须创建一个位图对象。如果您使用inJustDecodeBounds
标志位图将不会加载到内存中。事实上BitmapFactory.decodeFile
将返回null。在我的示例中,uri
是图像的物理路径
【讨论】:
但我在 logcat 上得到的宽度和高度为 0? 是的,我还发现 dropbox uri 以 file:// 开头,图库图片以 content:// 开头 @blackbelt 好的!但我的意思是请将decodeFile(uri.getPath()).getAbsolutePath(),
更改为decodeFile(new File(uri.getPath()).getAbsolutePath(),
这不是一个解决方案,因为 Uris 可能不是真正的文件。
使用此解决方案我得到 0 高度和 0 宽度【参考方案2】:
解决方案是使用new File(uri.getPath()).getAbsolutePath()
而不是uri.toString()
【讨论】:
谢谢。你节省了我的时间。 这不是一个解决方案,因为 Uris 可能不是真正的文件。【参考方案3】:Blackbelt 的答案大部分时间都可以使用Options
,但我想使用ExifInterface
提出另一种解决方案或备用解决方案。如果您有图像 URI,则可以使用完整路径创建 ExifInterface
,不需要位图对象或 BitmapFactory.Options
。
例如
int width = exif.getAttributeInt( ExifInterface.TAG_IMAGE_WIDTH, defaultValue );
int height = exif.getAttributeInt( ExifInterface.TAG_IMAGE_LENGTH, defaultValue );
【讨论】:
【参考方案4】:除了@Blackbelt 答案,您还应该使用以下代码从 Uri 检索文件路径:
public static String getPathFromURI(Context context, Uri contentUri)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT &&
DocumentsContract.isDocumentUri(context, contentUri))
return getPathForV19AndUp(context, contentUri);
else
return getPathForPreV19(context, contentUri);
private static String getPathForPreV19(Context context, Uri contentUri)
String[] projection = MediaStore.Images.Media.DATA ;
Cursor cursor = context.getContentResolver().query(contentUri, projection, null, null, null);
if (cursor != null && cursor.moveToFirst())
try
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
return cursor.getString(columnIndex);
finally
cursor.close();
return null;
@TargetApi(Build.VERSION_CODES.KITKAT)
private static String getPathForV19AndUp(Context context, Uri contentUri)
String documentId = DocumentsContract.getDocumentId(contentUri);
String id = documentId.split(":")[1];
String[] column = MediaStore.Images.Media.DATA ;
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = context.getContentResolver().
query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[] id , null);
if (cursor != null)
try
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst())
return cursor.getString(columnIndex);
finally
cursor.close();
return null;
【讨论】:
【参考方案5】:如果您有文件 uri,Blackbelt 的答案是正确的。但是,如果您使用official camera tutorial 中的新文件提供程序,它将不起作用。这适用于这种情况:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(
getContext().getContentResolver().openInputStream(mPhotoUri),
null,
options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
【讨论】:
感谢您的解决方案。它能够获得content://media/external/images/media/272
的高度宽度。但是,高度和宽度被还原(imageHeight = 实际宽度和 imageWidth = 实际高度)。你知道怎么解决吗?
@h8pathak 我不再了解这些东西了。随意编辑它,或评论确切的代码,我会编辑它。【参考方案6】:
这个set of utilities 在 android 中使用 Size 抽象。
它包含一个类SizeFromImage.java 你可以这样使用它:
ISize size = new SizeFromImage(imgFilePath);
size.width();
size.hight();
【讨论】:
【参考方案7】:接受的答案返回宽度/高度为 0,通过将 uri.getPath() 替换为 uri.getLastPathSegment(),它返回正确的尺寸
public static int[] getImageDimension(Uri uri)
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(new File(uri.getLastPathSegment()).getAbsolutePath(), options);
return new int[]options.outWidth, options.outHeight;
【讨论】:
【参考方案8】:对于具有内容 uri(以 content://
开头)的人,打开一个 InputStream
并解码该流以避免获得 0 宽度和高度。我将使用 Kotlin
val uri: Uri = ....
val options = BitmapFactory.Options().apply inJustDecodeBounds = true
val inputStream = contentResolver.openInputStream(uri)
BitmapFactory.decodeStream(inputStream, null, options)
val width = options.outWidth
val height = options.outHeight
【讨论】:
【参考方案9】:请使用输入流:
public int[] getImageSize(Uri uri)
try
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
InputStream input = this.getContentResolver().openInputStream(uri);
BitmapFactory.decodeStream(input, null, options); input.close();
return new int[]options.outWidth, options.outHeight;
catch (Exception e)
return new int[]0,0;
它会以数组形式返回:
int[] width , height
【讨论】:
一个解决问题的答案【参考方案10】:如果你们的宽度和高度一直是 (0,0),那么您可能想要解码一个流,而不是一个文件。
这可能是因为您正试图从资产中读取图像。试试这个:
val b = BitmapFactory.decodeStream(context.assets.open("path/in/assets/img.png"))
val width = b.width
val height = b.height
【讨论】:
以上是关于我可以从android中的uri获取图像文件的宽度和高度吗?的主要内容,如果未能解决你的问题,请参考以下文章