android - 选择图像时无法解码流

标签 android image decode android-bitmap

在我的应用程序中从图库中选择图像时,它不会崩溃,而是无法解码路径流。直接从相机拍摄照片工作正常,但从图库中它不在这里是我的 Activity 结果中的代码。

//enter code here
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Uri selectedImageUri = null;
    String filePath = null;
    switch (requestCode) {
        case PICK_IMAGE:
            if (resultCode == Activity.RESULT_OK)
            {
                selectedImageUri = data.getData();
                name = getPath(selectedImageUri);
            }
            break;
        case PICK_Camera_IMAGE:
            if (resultCode == RESULT_OK) {
                //use imageUri here to access the image
                selectedImageUri = imageUri;
            } else if (resultCode == RESULT_CANCELED) {
                Toast.makeText(this, "Picture was not taken", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "Picture was not taken", Toast.LENGTH_SHORT).show();
            }
            break;
    }
    if(selectedImageUri != null)
    {
        try
        {
            // OI FILE Manager
            String filemanagerstring = selectedImageUri.getPath();


            // MEDIA GALLERY
            String selectedImagePath = getPath(selectedImageUri);

            if (selectedImagePath != null) {
                filePath = selectedImagePath;

            } else if (filemanagerstring != null) {
                filePath = filemanagerstring;
            } else {
                Toast.makeText(getApplicationContext(), "Unknown path",
                        Toast.LENGTH_LONG).show();
                Log.e("Bitmap", "Unknown path");
            }

            if (filePath != null)
            {
                decodeFile(filePath);
            } else {
                bitmap = null;
            }
        }
        catch (Exception e)
        {
            Toast.makeText(getApplicationContext(), "Internal error",
                    Toast.LENGTH_LONG).show();
            Log.e(e.getClass().getName(), e.getMessage(), e);
        }
    }
}
  public String getPath(Uri uri)
  {
    // just some safety built in
    if( uri == null ) {
        // TODO perform some logging or show user feedback
        return null;
    }
    // try to retrieve the image from the media store first
    // this will only work for images selected from gallery
    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = managedQuery(uri, projection, null, null, null);
    if( cursor != null ){
        int column_index = cursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }
    // this is our fallback here
    return uri.getPath();
}
public void decodeFile(String filePath)
{
    // Decode image size
    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(filePath, o);

    // The new size we want to scale to
    final int REQUIRED_SIZE = 1024;

    // Find the correct scale value. It should be the power of 2.
    int width_tmp = o.outWidth, height_tmp = o.outHeight;
    int scale = 1;
    while (true)
    {
        if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
            break;
        width_tmp /= 2;
        height_tmp /= 2;
        scale *= 2;
    }

    // Decode with inSampleSize
    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = scale;
    bitmap = BitmapFactory.decodeFile(filePath, o2);

    //imgView.setImageBitmap(bitmap);

}

如有任何帮助,我们将不胜感激。

最佳答案

在更高版本的 Android ( KitKat and above ) 中,从图库选择器返回的 Uri 的格式已经改变,并不总是可以从 Uri 获取文件路径 没有很多麻烦,有时根本不可能。因此,最好直接使用 Uri 解码位图。

更改您的 decodeFile() 函数以接受 Uri 并使用 BitmapFactory.decodeStream() 解码图像,像这样:

public void decodeFile(Uri fileUri)
{
    // Decode image size
    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(getContentResolver().openInputStream(fileUri), null, o);

    // The new size we want to scale to
    final int REQUIRED_SIZE = 1024;

    // Find the correct scale value. It should be the power of 2.
    int width_tmp = o.outWidth, height_tmp = o.outHeight;
    int scale = 1;
    while (true)
    {
        if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
            break;
        width_tmp /= 2;
        height_tmp /= 2;
        scale *= 2;
    }

    // Decode with inSampleSize
    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = scale;
    bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(fileUri), null, o2);

    //imgView.setImageBitmap(bitmap);

}

然后您可以将您的 onActivityResult() 代码简化为:

if(selectedImageUri != null)
{
    try
    {
        decodeFile(selectedImageUri);
    }
    catch (Exception e)
    {
        Toast.makeText(getApplicationContext(), "Internal error",
                Toast.LENGTH_LONG).show();
        Log.e(e.getClass().getName(), e.getMessage(), e);
    }
}

如果您在获取有效的 Uri 时遇到问题,请参阅 this question 的已接受答案了解如何在 OnActivityResult() 中获取 Uri 并具有 KitKat 及更高版本的正确权限。

关于android - 选择图像时无法解码流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28218419/

相关文章:

android - 在android中解析xlink类型的XML

image - Matlab 中的 Geoshow - 打印到 tiff 文件时面部颜色发生变化

javascript - jQuery .hover 和 .mouseleave 意外循环。我该如何解决

java - Java AudioSystem.getAudioFileTypes()在android中返回空数组

Android sqlite 查询与 AND

android - Android Webview文件和相机上传-Kotlin

android - Kotlin .TypeCastException : null cannot be cast to non-null type

image - ExpressJS : Retrieving images from MongoDB and displaying them in Jade

r - 如何在 R 中解压缩 base64 编码的字符串?

java - 获取 org.json.JSONEXCEPTION : Unteterminated object at character when decoding token