Android developers mostly face out of memory error when loading images into imageView. Primarily this error is raised because we try to load very large image and there is not much memory available. To prevent this, this is good idea to scale down the image according to imageView height/width. setScaledAvatar() method is doing this scaling.
private void setScaledAvatar(String avatarPath, ImageView imageView) { // Get the dimensions of the View int targetW = imageView.getWidth(); int targetH = imageView.getHeight(); // Get the dimensions of the bitmap BitmapFactory.Options bmOptions = new BitmapFactory.Options(); bmOptions.inJustDecodeBounds = true; BitmapFactory.decodeFile(avatarPath, bmOptions); int photoW = bmOptions.outWidth; int photoH = bmOptions.outHeight; if (targetW == 0 || targetH == 0) { throw new RuntimeException("ImageView height or width is zero"); } // Determine how much to scale down the image int scaleFactor = Math.min(photoW / targetW, photoH / targetH); // Decode the image file into a Bitmap sized to fill the View bmOptions.inJustDecodeBounds = false; bmOptions.inSampleSize = scaleFactor; bmOptions.inPurgeable = true; Bitmap bitmap = BitmapFactory.decodeFile(avatarPath, bmOptions); imageView.setImageBitmap(bitmap); }
However if you want to use this method on activity onCreate, this will throw divided by zero exception. why? because in onCreate, view are not yet actually drawn and imageView height and width are zero. To handle this situation,we can getViewTree observer and override addGlobalLayout method to for scalling image according to imageView height/width.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_fragment); String path = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES).getAbsolutePath() + "/" + "sample.png"; ImageView avatar = (ImageView) findViewById(R.id.ivAvatar); avatar.getViewTreeObserver().addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { if (path != null && avatar != null) { setScaledAvatar(path, avatar); } } }); }