【问题标题】:Picasso fails to load large images (from Camera and local Uri)Picasso 无法加载大图像(来自相机和本地 Uri)
【发布时间】:2016-11-10 02:54:30
【问题描述】:

我在使用 Picasso 时遇到问题,尝试从图库和相机意图中的格式 content://com.android.providers.media.documents/document/imageXXYYZZ 的本地 Uri 加载大图像.

我正在使用标准调用加载图像:

Picasso.load(image_url)
        .resize(600, 240)
        .centerCrop()
        .into(imageTarget);

我在这里附加了一个Target,当我触发onBitmapFailed(Drawable errorDrawable) 错误时。另外,当我登录毕加索时,我得到:

06-23 12:13:54.267  22393-22393/it.b3lab.friendipity D/Picasso﹕ Main        created      [R100] Request{content://com.android.providers.media.documents/document/image%3A13345 resize(600,240) centerCrop}
06-23 12:13:54.277  22393-23010/it.b3lab.friendipity D/Picasso﹕ Dispatcher  enqueued     [R100]+9ms
06-23 12:13:54.285  22393-23038/it.b3lab.friendipity D/Picasso﹕ Hunter      executing    [R100]+15ms
06-23 12:13:54.813  22393-23010/it.b3lab.friendipity D/Picasso﹕ Dispatcher  batched      [R100]+546ms for error
06-23 12:13:55.014  22393-23010/it.b3lab.friendipity D/Picasso﹕ Dispatcher  delivered    [R100]+746ms
06-23 12:13:55.024  22393-22393/it.b3lab.friendipity I/picasso﹕ failed to load bitmap
06-23 12:13:55.024  22393-22393/it.b3lab.friendipity D/Picasso﹕ Main        errored      [R100]+756ms

只有当我尝试从图库(大约 1 MB 以上)和使用高分辨率相机智能手机(在我的情况下是在 Android 上运行的 Moto G)时从相机意图加载大图像时,才会发生这种情况5.0.1)。我在 Android 4.4 上使用 Samsung S2 时没有收到此错误。

任何帮助将不胜感激!谢谢

【问题讨论】:

    标签: android camera picasso


    【解决方案1】:

    您需要将内容 uri 解析为绝对 uri。比如这样:

    public String getAbsolutePathFromURI( Uri contentUri ) {
      String[] proj = { MediaStore.Images.Media.DATA };
      Cursor cursor = activity.getContentResolver().query( contentUri, proj, null, null, null );
      int columnIndex = cursor.getColumnIndexOrThrow( MediaStore.Images.Media.DATA );
      cursor.moveToFirst();
      String path = cursor.getString( columnIndex );
      cursor.close();
      return path;
    }
    

    【讨论】:

    • 感谢您的回答,但使用此方法毕加索不会加载任何图像。我想问题可能是MediaStore.Images.Media.DATA应该根据我保存图像的位置来设置吧?
    • 正确。列名可能会有所不同。
    • 我应该查看哪一列?我将图片保存到File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),图片类型为MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE
    【解决方案2】:

    我花了很多时间研究如何使用 Picasso 将大图像加载到图像视图中。它在 genymotion 上工作,但在我的 moto x 上没有工作。所以我最终决定在异步任务中手动调整图像大小,然后将其加载到图像视图中不使用毕加索

    new AsyncTask<String, Void, Void>() {
                    @Override
                    protected Void doInBackground(String... params) {
                        String path = params[0];
                        final Bitmap resizedBitmap = ImageUtils.getResizedBitmap(200, 200, PATH_TO_IMAGE);
                        getActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                imageView.setImageBitmap(resizedBitmap);
                            }
                        });
                        return null;
                    }
                }.execute(imageLoadPath);
    

    你可以找到ImageUtils.getResizedBitmap()方法here

    【讨论】:

      【解决方案3】:

      毕加索失败了,但这很完美

         public static void resizeImage(String file, int maxTargetWidth, int maxTargetHeight) {
          try {
              InputStream in = new FileInputStream(file);
      
              BitmapFactory.Options options = new BitmapFactory.Options();
              options.inJustDecodeBounds = true;
              BitmapFactory.decodeStream(in, null, options);
              close(in);
      
              int inWidth = options.outWidth;
              int inHeight = options.outHeight;
      
              in = new FileInputStream(file);
              options = new BitmapFactory.Options();
              options.inSampleSize = Math.max(inWidth / maxTargetWidth, inHeight / maxTargetHeight);
              Bitmap roughBitmap = BitmapFactory.decodeStream(in, null, options);
      
              Matrix m = new Matrix();
              RectF inRect = new RectF(0, 0, roughBitmap.getWidth(), roughBitmap.getHeight());
              RectF outRect = new RectF(0, 0, maxTargetWidth, maxTargetHeight);
              m.setRectToRect(inRect, outRect, CENTER);
              float[] values = new float[9];
              m.getValues(values);
      
              Bitmap resizedBitmap = createScaledBitmap(roughBitmap,
                      (int) (roughBitmap.getWidth() * values[0]), (int) (roughBitmap.getHeight() * values[4]),
                      true);
      
              resizedBitmap = rotateBitmap(file, resizedBitmap);
              FileOutputStream out = new FileOutputStream(file);
              resizedBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
              close(out);
          } catch (Exception e) {
              error(e);
          }
      }
      
      private static Bitmap rotateBitmap(String src, Bitmap bitmap) {
          try {
              int orientation = new ExifInterface(src).getAttributeInt(TAG_ORIENTATION, 1);
              Matrix matrix = new Matrix();
              if (orientation == ORIENTATION_NORMAL) return bitmap;
              if (orientation == ORIENTATION_FLIP_HORIZONTAL) matrix.setScale(-1, 1);
              else if (orientation == ORIENTATION_ROTATE_180) matrix.setRotate(180);
              else if (orientation == ORIENTATION_FLIP_VERTICAL) {
                  matrix.setRotate(180);
                  matrix.postScale(-1, 1);
              } else if (orientation == ORIENTATION_TRANSPOSE) {
                  matrix.setRotate(90);
                  matrix.postScale(-1, 1);
              } else if (orientation == ORIENTATION_ROTATE_90) {
                  matrix.setRotate(90);
              } else if (orientation == ORIENTATION_TRANSVERSE) {
                  matrix.setRotate(-90);
                  matrix.postScale(-1, 1);
              } else if (orientation == ORIENTATION_ROTATE_270) {
                  matrix.setRotate(-90);
              } else return bitmap;
              try {
                  Bitmap oriented = createBitmap(bitmap, 0, 0,
                          bitmap.getWidth(), bitmap.getHeight(), matrix, true);
                  bitmap.recycle();
                  return oriented;
              } catch (OutOfMemoryError e) {
                  error(e);
              }
          } catch (IOException e) {
              error(e);
          }
          return bitmap;
      }
      

      【讨论】:

        【解决方案4】:

        试试这个:

        Uri uri = Uri.parse(imageUri);
        Picasso.with(context)
            .load(uri)
            .fit()
            .resize(600, 240)
            .skipMemoryCache()
            .transform(new DocumentExifTransformation(this, uri))
            .into(imageView);
        

        如果我不工作,请看这里https://github.com/square/picasso/issues/539

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-08-26
          • 1970-01-01
          • 1970-01-01
          • 2019-09-18
          • 2018-06-02
          • 2020-08-03
          • 1970-01-01
          相关资源
          最近更新 更多