2

My app displays a large number of images. Rather than resizing all of these (when I did resize one, it was too small and didn't occupy all of the ImageView), is there any reason that I can't place these images in drawable-nodpi and then resize them with the following code:

public class SingleGameTixFragment extends Fragment {
    int arenaX, arenaY, pricesX, pricesY;
    ImageView mArenaImageView, mPricesImageView;

    public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;
    }

    public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
                                                         int reqWidth, int reqHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.tickets_singlegametix, container,  false);

        mPricesImageView = (ImageView)v.findViewById(R.id.tickets_singleGameTix_prices);

        mPricesImageView.setImageResource(R.drawable.tickets_singlegametix_prices);

        mArenaImageView = (ImageView)v.findViewById(R.id.tickets_singleGameTix_arena);
        //mArenaImageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(), R.drawable.arena, arenaImageView.getWidth(), arenaImageView.getHeight()));

        mArenaImageView.setImageResource(R.drawable.tickets_arena);

        //ImageView backgroundImageView = (ImageView)v.findViewById(R.id.backgroundImageView);
        //backgroundImageView.setImageResource(R.drawable.crowdbackground);

        v.post(new Runnable() {
            @Override
            public void run() {
                arenaX = mArenaImageView.getWidth();
                arenaY = mArenaImageView.getHeight();
                pricesX = mPricesImageView.getWidth();
                pricesY = mPricesImageView.getHeight();

                mPricesImageView.setImageBitmap(
                        decodeSampledBitmapFromResource(getResources(), R.drawable.singleprices, arenaX, arenaY));
            }
        });

        return v;
    }
}

Most of these images are large and, without scaling, cause OOM errors. However, with the above code I haven't yet had an error.

Jameson
  • 4,198
  • 4
  • 17
  • 31
  • Thanks for the suggestion. I'm still wondering how to handle large images in Android. We have some full-screen backgrounds that are causing OOM. I have now replaced PNGs with JPGs and also moved to `drawable-nodpi` as [this answer](http://stackoverflow.com/a/14877627/1121497) suggests. I hope I can avoid or at least reduce OOMs. – Ferran Maylinch Sep 28 '15 at 14:19
  • I have also discovered the http://tinypng.com tool, which can reduce some images quite a lot. – Ferran Maylinch Sep 28 '15 at 14:28

2 Answers2

0

I've used this same technique for the same reason and with good results, although the power-of-two sampling method isn't quite as smooth as a full size scaling operation.

Depending on the type of images, you could consider using VectorDrawable instead.

Rupert Rawnsley
  • 2,622
  • 1
  • 29
  • 40
0

if you don't want to put the images in different folder, you can just place it in a drawable folder. create a drawable folder and place all content that is dpi independent over there.

Ibukun Muyide
  • 1,294
  • 1
  • 15
  • 23