我可以从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获取图像文件的宽度和高度吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何从android pie中的内容uri获取文件路径

Android 从 Intent 获取裁剪图像的 URI

从内容 URI 中获取搜索图像的绝对文件路径

Android - 如何从原始文件中获取 Uri?

Android相机:拍照后获取图片Uri

获取存储在 sd 卡 + android 中的图像的缩略图 Uri/路径