0

我在尝试将图像转换为位图以显着缩小图像时收到FileNotFound异常。Android通过Uri和位图缩放图库中的图像

我从图库中检索用户选择的图像,像这样

public static void GET_PICTURE_FROM_GALLERY (Activity activity) 
{ 
    Intent getIntent = new Intent(Intent.ACTION_GET_CONTENT); 
    getIntent.setType("image/*"); 

    Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); 
    pickIntent.setType("image/*"); 

    Intent chooserIntent = Intent.createChooser(getIntent, "Select Image"); 
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] {pickIntent}); 

    activity.startActivityForResult(chooserIntent, REQUEST_SELECT_PHOTO); 
} 

然后,当用户完成采摘:

public void setChosenPicture (Activity activity, Intent data) 
{ 
    if(editingViewHelper != null) 
    { 
     String[] filePathColumn = {MediaStore.Images.Media.DATA}; 

     Uri selectedImage = data.getData(); 

     System.out.println("GOT URI: " + selectedImage.toString()); 

     Cursor cursor = activity.getContentResolver().query(selectedImage, filePathColumn, null, null, null); 
     cursor.moveToFirst(); 

     int columnIndex = cursor.getColumnIndex(filePathColumn[0]); 
     editingViewHelper.holder.tempUri = Uri.parse(cursor.getString(columnIndex)); 

     System.out.println("SET URI: " + editingViewHelper.holder.tempUri.toString()); 

     cursor.close(); 

     editingViewHelper.holder.imageView.setImageURI(editingViewHelper.holder.tempUri); 
    } 
} 

此输出以下:

GOT URI: content://media/external/images/media/110 
SET URI: /storage/emulated/0/DIRECTORY/IMG_20170606_154512_1664512804.jpg 

现在这个工程很好,但只有当我调用imageView.setImageUri(uri);但是,我不能这样做,因为我必须缩小图像的大小,所以应用程序不会使用大量的内存。要做到这一点,我有这样的方法

public static Bitmap decodeUri(Context c, Uri uri, final int requiredSize) 
{ 
    System.out.println("URI: " + uri.toString()); 

    try 
    { 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 

//This line is where the error occurs. 
    BitmapFactory.decodeStream(c.getContentResolver().openInputStream(uri), null, o); 

     int width_tmp = o.outWidth; 
     int height_tmp = o.outHeight; 
     int scale = 1; 

     while(true) 
     { 
      if(width_tmp/2 < requiredSize || height_tmp/2 < requiredSize) 
       break; 

      width_tmp /= 2; 
      height_tmp /= 2; 
      scale *= 2; 
     } 

     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize = scale; 

     return BitmapFactory.decodeStream(c.getContentResolver().openInputStream(uri), null, o2); 
    } 
    catch (FileNotFoundException e) 
    { 
     e.printStackTrace(); 
     return null; 
    } 
} 

最后,我有以下.OUTPUT FileNotFound例外

URI: /storage/emulated/0/DIRECTORY/IMG_20170606_154512_1664512804.jpg 
java.io.FileNotFoundException: No content provider: /storage/emulated/0/DIRECTORY/IMG_20170606_154512_1664512804.jpg 

现在奇怪的是,这种方法确实工作但如果仅仅是通过我的应用程序中的图片采取 Uri。这是最后的方法的输出例子不抛出任何错误

Uri: content://com.subliroid.dinnerdecider.provider/external_files/Pictures/DIRECTORY/IMG_20170606_154512_1664512804.jpg 

我能够调用imageView.setImageUri(URI)与这两种类型的URI,但我不能缩放一种类型了。直到我开始在需要4k +图片的真实设备上测试我的应用程序为止,我才能忽略这一点。

回答

1

最简单的事情,到目前为止,是删除大部分的这段代码,并使用现有的image-loading library。 Google建议Glide;我用过Picasso,还有很多其他的。

然后,当用户完成采摘:

query()电话将在许多情况下,失败(移动存储的图像,用户的选择,你可能不响应预期应用到你的Intent等)。

最后,我有.OUTPUT FileNotFound例外以下

您不必要创建新Uri,而你这样做不正确的,因为你正在传递到Uri.parse()值不具有方案。

如果您不打算使用现有的已调试代码(即图像加载库),请通过Uri,将onActivityResult()中的代码传递给您的位图缩放代码。然后,找出何时将主要应用程序线程的大部分逻辑移出,因为您正在冻结当前实现中的UI。