Set max width for uploading images with Picasso

I have a fixed header in my activity that I need to dynamically load images into it. I need these images to fill this header completely, keep the width and height proportions.

If I load the image before, I get an OutOfMemoryException. If I use Picasso's fit () method, there will be white space in the area. And if I use Transformation as some people on StackOverflow have suggested, I also get an OutOfMemoryException.

How can I solve this?

XML header:

<FrameLayout
        android:id="@+id/headerContainer"
        android:layout_width="match_parent"
        android:layout_height="140dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:background="#ffd5d5d5">


        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/imageView4"
            android:layout_gravity="center"
            android:src="@drawable/background_camera" />

        <ViewFlipper
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/viewFlipper"
            android:layout_gravity="center" >

        </ViewFlipper>


        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Adicionar foto do estacionamento"
            android:id="@+id/textAddPhotos"
            android:layout_gravity="center"
            android:textColor="#ff757575"
            android:padding="10dp" />

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:clickable="true"
            android:id="@+id/addPhotosArea"></RelativeLayout>

    </FrameLayout>

      

Images are added to the ViewFlipper programmatically using the following code:

final ImageView imageView = new ImageView(SuggestionActivity.this);
        imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

        Picasso.with(SuggestionActivity.this).load(selectedImageUri)
                .fit().centerInside()
                .into(imageView);

        mViewFlipper.addView(imageView);

      


UPDATE

I figured out that Picasso was calculating the size incorrectly when loading an image with exif = 90º orientation.

I'm trying to change its source, but the logic is pretty confusing.

I think the problem is with this function of the BitmapHunter.java file:

static Bitmap transformResult(Request data, Bitmap result, int exifRotation) {
    int inWidth = result.getWidth();
    int inHeight = result.getHeight();

    int drawX = 0;
    int drawY = 0;
    int drawWidth = inWidth;
    int drawHeight = inHeight;

    Matrix matrix = new Matrix();

    if (data.needsMatrixTransform()) {
      int targetWidth = data.targetWidth;
      int targetHeight = data.targetHeight;

      float targetRotation = data.rotationDegrees;
      if (targetRotation != 0) {
        if (data.hasRotationPivot) {
          matrix.setRotate(targetRotation, data.rotationPivotX, data.rotationPivotY);
        } else {
          matrix.setRotate(targetRotation);
        }
      }

      if (data.centerCrop) {
        float widthRatio = targetWidth / (float) inWidth;
        float heightRatio = targetHeight / (float) inHeight;
        float scale;
        if (widthRatio > heightRatio) {
          scale = widthRatio;
          int newSize = (int) Math.ceil(inHeight * (heightRatio / widthRatio));
          drawY = (inHeight - newSize) / 2;
          drawHeight = newSize;
        } else {
          scale = heightRatio;
          int newSize = (int) Math.ceil(inWidth * (widthRatio / heightRatio));
          drawX = (inWidth - newSize) / 2;
          drawWidth = newSize;
        }
        matrix.preScale(scale, scale);
      } else if (data.centerInside) {
        float widthRatio = targetWidth / (float) inWidth;
        float heightRatio = targetHeight / (float) inHeight;
        float scale = widthRatio < heightRatio ? widthRatio : heightRatio;
        matrix.preScale(scale, scale);
      } else if (targetWidth != 0 && targetHeight != 0 //
          && (targetWidth != inWidth || targetHeight != inHeight)) {
        // If an explicit target size has been specified and they do not match the results bounds,
        // pre-scale the existing matrix appropriately.
        float sx = targetWidth / (float) inWidth;
        float sy = targetHeight / (float) inHeight;
        matrix.preScale(sx, sy);
      }
    }

    if (exifRotation != 0) {
      matrix.preRotate(exifRotation);
    }

    Bitmap newResult =
        Bitmap.createBitmap(result, drawX, drawY, drawWidth, drawHeight, matrix, true);
    if (newResult != result) {
      result.recycle();
      result = newResult;
    }

    return result;
  }

      

+3


source to share


2 answers


Use .fit (). centerCrop (), it should do what you are looking for.



+3


source


Before loading the image, the ImageView must be added to the ViewFlipper. This is so that Picasso knows the height / width of the ImageView, which should scale the image properly to the size of the ImageView.

Change it to:



final ImageView imageView = new ImageView(SuggestionActivity.this);
imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

mViewFlipper.addView(imageView);

Picasso.with(SuggestionActivity.this).load(selectedImageUri)
        .fit().centerInside()
        .into(imageView);

      

+2


source







All Articles