如何从文件管理器中获取位图?

How to get bitmap from file manager?

我将在我的 android 应用程序中创建附件。我需要附上图片。 这是我的代码:

...
attachButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
            intent.setType("image/*");
            startActivityForResult(Intent.createChooser(intent, "Select image"), CHOOSE_IMAGE);
        }
    });
...


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode == CHOOSE_IMAGE) {
        if(resultCode == RESULT_OK) {
            Uri uri = data.getData();
            ImageView imageView = new ImageView(this);

            Bitmap bitmap = getDecodedImageFromUri(uri);
            imageView.setImageBitmap(bitmap);
         }
    }
 }

 private Bitmap getDecodedImageFromUri(Uri uri) {
    InputStream inputStream = null;
    try {
        inputStream = getContentResolver().openInputStream(uri);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    Rect rect = new Rect(0, 0, 0, 0);
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;

    BitmapFactory.decodeStream(inputStream, rect, options);
    options.inSampleSize = getInSampleSize(options, 128, 128);

    options.inJustDecodeBounds = false;
    Bitmap bitmap = BitmapFactory.decodeStream(inputStream, rect, options); //HERE IS PROBLEM - bitmap = null.
    return bitmap;
}

private int getInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
    int width = options.outWidth;
    int height = options.outHeight;
    int inSampleSize = 1;

    if(height > reqHeight || width > reqWidth) {
        int halfHeight = height / 2;
        int halfWidth = width / 2;

        while ((halfHeight / inSampleSize) > reqHeight &&
                (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

我在问题的地方添加评论。 所以,我调试了一下,在这一刻:

 Bitmap bitmap = BitmapFactory.decodeStream(inputStream, rect, options);

位图等于空。

有什么问题吗?我做错了什么?

如您所见,这些辅助方法来自 android 开发人员指南。

已更新

我需要解码两次,因为我需要获取选项,然后获取图像大小来计算 InSampleSize 以压缩此图像。

第二次,选项不等于 null - 我通过调试检查了它。

但是,在第二次解码选项后,outWidth 和 outHeight 为 -1。所以,它设置为默认值。我不知道这一刻会发生什么。

你可以试试BitmapFactory.decodeStream(inputStream, null, options);

我猜你的问题可能是因为调用 decodeStream 两次

BitmapFactory.decodeStream(inputStream, rect, options); //HERE
options.inSampleSize = getInSampleSize(options, 128, 128);

options.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeStream(inputStream, rect, options); //HERE AGAIN
return bitmap;

根据文档,BitmapFactory.Options 的默认构造函数可能会给您带来这个麻烦:

BitmapFactory.Options() Create a default Options object, which if left unchanged will give the same result from the decoder as if null were passed.

如果选项参数为空(或行为为空),则结果将为空:

The decoded bitmap, or null if the image data could not be decoded, or, if opts is non-null, if opts requested only the size be returned (in opts.outWidth and opts.outHeight)

尝试制作更好的选项对象或使用方法

public static Bitmap decodeStream (InputStream is)

如果你这样尝试会怎样:

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