25

This is a part of my Activity:

private ImageView mImageView;
private int resource;

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  resource = getIntent().getIntExtra("res", -1);

  Matrix initMatrix = new Matrix();

  mImageView = new ImageView(getApplicationContext());
  mImageView.setScaleType( ImageView.ScaleType.MATRIX );
  mImageView.setImageMatrix( initMatrix );
  mImageView.setBackgroundColor(0);
  mImageView.setImageResource(resource);
}

I try to display an image within an ImageView using a matrix as scale type (I want to add multitouch later). But before user starts interaction i want the image to be centered and fit inside the ImageView. I already found answers concerning how to solve it but there is one problem for me: to make image centered using matrix I need to know its width and height. Is there any way of getting image size when all you have is int resource ?

Manuel Allenspach
  • 12,467
  • 14
  • 54
  • 76
alex
  • 10,900
  • 15
  • 70
  • 100

2 Answers2

49

Use BitmapFactory.decodeResource to obtain a Bitmap object of the resource, and then from the bitmap you can easily retrieve the image width/height with getHeight and getWidth

Also do not forget to recycle your bitmap

EDIT:

This way you will get a null bitmap as output, but the BitmapFactory.Options will be set with the with and height for the bitmap. So, in this case,, you do not need to recycle the bitmap

BitmapFactory.Options dimensions = new BitmapFactory.Options(); 
dimensions.inJustDecodeBounds = true;
Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bitmap, dimensions);
int height = dimensions.outHeight;
int width =  dimensions.outWidth;
Gal Bracha
  • 19,004
  • 11
  • 72
  • 86
Blackbelt
  • 156,034
  • 29
  • 297
  • 305
  • 14
    You should also use `BitmapFactory.Options dimensions = new BitmapFactory.Options(); dimensions.inJustDecodeBounds = true;` to just decode the image dimensions without actually loading the bitmap into memory. – dmon Mar 11 '12 at 15:13
  • For me why mBitmap is coming as null if I set inJustDecodeBounds = true? If I set it to false it is returning me a bitmap. – Ankit Jun 21 '13 at 08:04
  • @Ankit it is the normali behaviour and it is described in the documentation – Blackbelt Jun 21 '13 at 08:19
  • @blackbelt I just want to know the dimensions of image I don't want to load it in memory but with above code I am getting nullPointerException when calling getHeight() and getWidth(). – Ankit Jun 21 '13 at 13:02
  • 1
    @Ankit thanks to point out, it was a mistake. I have update my answer – Blackbelt Jun 21 '13 at 13:04
  • 1
    @blackbelt, great answer, should mention that after your EDIT you don't need to recycle the bitmap either (since you don't get one). – Raanan Nov 05 '13 at 12:50
  • @Raanan I am going to put it right now. Thanks for pointing it out – Blackbelt Nov 05 '13 at 12:55
  • @Blackbelt As far as I can tell, there is no need to recycle the bitmap. Maybe something has changed, but the docs state "This is an advanced call, and normally need not be called, since the normal GC process will free up this memory when there are no more references to this bitmap." and "This will not free the pixel data synchronously; it simply allows it to be garbage collected" --- No memory is freed by calling recycle until the next GC process, at which point the Bitmap is long out of scope. – user1122069 Apr 16 '16 at 07:31
  • @user1122069, there is no need anymore you are right. The real need was for really old platforms, up to gingerbread – Blackbelt Apr 16 '16 at 07:44
11

For anyone that didn't read dmon's comment. The code to do this looks like this:

final Options opt = new BitmapFactory.Options();
opt.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.drawable.your_photo, opt);

opt.outHeight; // height of resource
opt.outWidth; // width of resource
xbakesx
  • 13,202
  • 6
  • 48
  • 76