【问题标题】:can i get image file width and height from uri in android?我可以从android中的uri获取图像文件的宽度和高度吗?
【发布时间】: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;
}

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

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

【问题讨论】:

    标签: android image height width uri


    【解决方案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
              

              【讨论】:

                猜你喜欢
                • 2014-07-15
                • 2017-03-19
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-10-20
                • 2015-09-04
                • 1970-01-01
                相关资源
                最近更新 更多