Android: Slow performance using a big image in ImageView
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'
Related videos on Youtube
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, 2022Comments
-
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 almost 9 yearsThanks 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