繁体   English   中英

我可以从android中的uri获取图像文件的宽度和高度吗?

[英]can i get image file width and height from uri in android?

我可以正常通过MediaStore.Images.Media获取图像宽度

但我需要从 Dropbox 中选择的图像中获取图像的宽度和高度

所以目前我有以下方法从 Dropbox 获取图像大小

private void getDropboxIMGSize(Uri uri){
    String size = Long.toString(new File(uri.getPath()).length());
    return size;
}

但我真正需要的是获取文件的宽度和高度值

有人知道如何实现吗?请帮忙!

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

没有没有办法。 您必须创建一个 Bitmap 对象。 如果您使用inJustDecodeBounds标志,位图将不会加载到内存中。 事实上BitmapFactory.decodeFile将返回 null。 在我的示例中, uri是图像的物理路径

如果您有文件 uri,Blackbelt 的答案是正确的。 但是,如果您像 官方相机教程那样使用新的文件提供程序,它将不起作用。 这适用于这种情况:

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;

Blackbelt 的答案大部分时间都可以使用Options ,但我想通过使用ExifInterface提出另一种解决方案或后备解决方案。 如果您有图像 URI,则可以使用完整路径创建ExifInterface ,不需要 Bitmap 对象或BitmapFactory.Options

前任。

int width = exif.getAttributeInt( ExifInterface.TAG_IMAGE_WIDTH, defaultValue );
int height = exif.getAttributeInt( ExifInterface.TAG_IMAGE_LENGTH, defaultValue ); 

组实用程序与 Android 中的 Size 抽象一起使用。

它包含一个类SizeFromImage.java你可以这样使用它:

ISize size = new SizeFromImage(imgFilePath);
size.width();
size.hight();

解决方案是使用new File(uri.getPath()).getAbsolutePath()而不是uri.toString()

除了@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;
}

通过将 uri.getPath() 替换为 uri.getLastPathSegment(),接受的答案与我一起返回 0 的宽度/高度,它返回正确的尺寸

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

对于拥有内容 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

请使用输入流:

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 }

如果你们一直在宽度和高度上得到 (0,0),你可能想要解码一个流,而不是一个文件。

这可能是因为您试图从资产中读取图像。 试试这个:

val b = BitmapFactory.decodeStream(context.assets.open("path/in/assets/img.png"))
val width = b.width
val height = b.height

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM