Android: Slow performance using a big image in ImageView

前端 未结 2 930
遇见更好的自我
遇见更好的自我 2021-01-05 08:19

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

相关标签:
2条回答
  • 2021-01-05 08:57

    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.

    0 讨论(0)
  • 2021-01-05 09:02

    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'

    0 讨论(0)
提交回复
热议问题