11

How would I use picasso to crop an image to an ImageView?

Default seems to scale it down so the whole thing shows fit seems to stretch it. Centercrop by itself breaks. fit centercrop seems to be the same as just fit

Janusz
  • 176,216
  • 111
  • 293
  • 365
Fricken Hamster
  • 541
  • 3
  • 7
  • 15
  • 8
    Use `.fit().centerCrop()` [Answer, which help me a lot](http://stackoverflow.com/a/20824141/5439793) – Chuck Oct 07 '16 at 12:39

3 Answers3

13

Try using centerCrop()

Picasso.with(mContext)
.load(url)
.centerCrop()
.resize(yourImageView.getMeasuredWidth(),yourImageView.getMeasuredHeight())
.error(R.drawable.error)
.placeholder(R.drawable.blank_img)
.into(yourImageView);

You have to add addOnPreDrawListener listener otherwise you will get 0 for width and height when the imageview is not drawn. Go here for details on how to use addOnPreDrawListener.

Community
  • 1
  • 1
Lazy Ninja
  • 21,131
  • 9
  • 77
  • 99
  • 2
    centercrop by itself gives an error java.lang.IllegalStateException: Center crop requires calling resize with positive width and height. What is the error of Picasso mean? – Fricken Hamster May 09 '15 at 00:05
  • @FrickenHamster you are right. You need to add resize. Check my edit. – Lazy Ninja May 09 '15 at 00:30
  • This solution seems to just set the crop based on whatever values I have in resize. I would like it to crop based on the size of the imageview, which is located in a cardview – Fricken Hamster May 09 '15 at 01:59
8

CenterCrop() is a cropping technique that scales the image so that it fills the requested bounds of the ImageView and then crops the extra. The ImageView will be filled completely, but the entire image might not be displayed.

Picasso  
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.resize(600, 200) // resizes the image to these dimensions (in pixel)
.centerCrop() 
.into(imageViewResizeCenterCrop);

CenterInside() is a cropping technique that scales the image so that both dimensions are equal to or less than the requested bounds of the ImageView. The image will be displayed completely, but might not fill the entire ImageView.

Picasso  
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.resize(600, 200)
.centerInside() 
.into(imageViewResizeCenterInside);

The discussed options should cover your needs for functionality regarding image resizing and scaling. There is one last helper functionality of Picasso, which can be very useful: fit().

Picasso  
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.fit()
// call .centerInside() or .centerCrop() to avoid a stretched image
.into(imageViewFit);
iamsankalp89
  • 4,242
  • 2
  • 12
  • 35
lallu Sukendh
  • 151
  • 2
  • 2
3

You must call resize before calling centerCrop or centerInside() methods otherwise Picasso complains about target width/height being 0.

public class MainActivity extends Activity {
ImageView imageView;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    imageView = (ImageView) findViewById(R.id.imageView);
}

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    if (hasFocus) {
        Picasso.with(this)
                .load("http://i.imgur.com/removed.png")
                .resize(imageView.getMeasuredWidth(), imageView.getMeasuredHeight())
                .centerCrop() // or centerInside()
                .into(imageView);
    }
    super.onWindowFocusChanged(hasFocus);
}
}

And here's the imageView defined within layout:

 <ImageView
    android:layout_width="160dp"
    android:layout_height="160dp"
    android:id="@+id/imageView"
    />
Manish
  • 3,722
  • 1
  • 22
  • 33
  • 2
    I actually have the imageview inside a recyclerview, so getmeasuredwidth and height end up being 0 at onBindViewHolder. How would I get the size then? thanks – Fricken Hamster May 09 '15 at 01:41
  • 3
    @Fricken Hamster, maybe too late, but you can use Picasso's `.fit()`. It waits until `getMeasure` and than do the rest. – Nexen Feb 03 '16 at 10:46