Android: Slow performance using a big image in ImageView

10,151

Solution 1

That bitmap is huge. The 500k you mention is the compressed size. Images are uncompressed in memory when you use them. You're actually looking at 2048×1536×4 = 12582912 = over 12MB of memory use.

If you're on a device like Nexus 9 that has that screen resolution, then you can reasonably assume it also has the memory, GPU and bus bandwidth to deal with an image of that size. However, if you're on a lower resolution device (most devices are, keep in mind that even Full HD is just 65% as large), then this image is phenomenally wasteful of memory. You can buy low end devices today with a 240x320 screen, where a full screen bitmap is a mere 2.5% the size of your image.

You're going to have to scale that image when you load it. Use BitmapFactory.Options to set the desired size before loading the image.

Furthermore, you're putting text directly on top of it. Text rendering requires alpha transparency, which requires sampling the underlying image. If you can put the text on an opaque background and put that on top, you'll save some GPU load as well, but I'm actually not sure how much performance that's going to get you. It may not be so big a deal.

Solution 2

You can use Dave Morissey's Subsampling Scale Image View as a drop in replacement of the standard image view.

XML layout:

<com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" 
                    android:scaleType="fitXY"
                    android:id="@+id/photo"/>
            </RelativeLayout>

Set image in code and disable touch:

photo = (SubsamplingScaleImageView) view.findViewById(R.id.photo);
photo.setOnTouchListener(new View.OnTouchListener() {
                            @Override
                            public boolean onTouch(View v, MotionEvent event) {
                                return true;
                            }
                        });
photo.setImage(ImageSource.uri(Uri.fromFile(new File("/somepath/file.png"))));

build.gradle:

compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.6.0'

Share:
10,151

Related videos on Youtube

Diego Alejandro Ossa
Author by

Diego Alejandro Ossa

I'm Diego Ossa, Game Developer from Medellín, Colombia, I love to have fun when I'm working, that's the way to make awesome stuff. My approach to work is marked by attention to detail in everything I do and I strive to find creative and efficient solutions to every problem. I have the ability to merge logic and creativity to create original, usable and high quality results. Curiosity, perseverance, and constant desire to learn make me a competitive person, always ready to face any problem or challenge.

Updated on September 15, 2022

Comments

  • Diego Alejandro Ossa
    Diego Alejandro Ossa almost 2 years

    I have an Activity where I have a background image in an ImageView, and nine transparent buttons on top of the image.

    http://i.stack.imgur.com/GGQqd.png

    When I tap any of the buttons I make a RelativeLayout appears in the top of the background.

    http://i.stack.imgur.com/JvKQK.jpg

    The problem is: When I use a big resolution image as a background in the layout the performance is very poor.

    I'm using a PNG image of 2048 x 1536, and it's weight is about 500k. When I use a smaller image like 1024 x 768 the application works fine, but it looks terrible.

    Is there a restriction or a method to use big images without losing performance?

  • Diego Alejandro Ossa
    Diego Alejandro Ossa almost 9 years
    Thanks for the answer. For example I'm testing the application on a 2560 x 1600 tablet and the background doesn't look very good if I scale down it. I'm trying to use the BitmapFactory.Options