Вы находитесь на странице: 1из 5

Skip to content

Developers

DESIGN

DEVELOP

DISTRIBUTE

navigation

Training

Getting Started
Building Apps with Content Sharing
Building Apps with Multimedia
Building Apps with Graphics & Animation
Displaying Bitmaps Efficiently
Loading Large Bitmaps Efficiently
Processing Bitmaps Off the UI Thread
Caching Bitmaps
Managing Bitmap Memory
Displaying Bitmaps in Your UI

o
o
o

Displaying Graphics with OpenGL ES


Animating Views Using Scenes and Transitions
Adding Animations
Building Apps with Connectivity & the Cloud
Building Apps with Location & Maps
Building Apps with User Info & Sign-In
Building Apps for Wearables
Building Apps for TV
Building Apps for Auto
Best Practices for Interaction & Engagement
Best Practices for User Interface
Best Practices for User Input
Best Practices for Background Jobs
Best Practices for Performance
Best Practices for Security & Privacy
Best Practices for Permissions & Identifiers
Best Practices for Testing
Using Google Play to Distribute & Monetize

HOME

DESIGN

DEVELOP

o
o
o

Training
API Guides
Reference

o
o
o
o

Samples
Android Studio
Android NDK
Google Services

DISTRIBUTE

Develop
Training
Building Apps with Graphics & Animation
Displaying Bitmaps Efficiently

Loading Large Bitmaps


Efficiently
PreviousNext

This lesson teaches you to


1. Read Bitmap Dimensions and Type
2. Load a Scaled Down Version into Memory

Try it out
DOWNLOAD THE SAMPLE
DisplayingBitmaps.zip

Images come in all shapes and sizes. In many cases they are larger than required for a typical
application user interface (UI). For example, the system Gallery application displays photos taken
using your Android devices's camera which are typically much higher resolution than the screen
density of your device.
Given that you are working with limited memory, ideally you only want to load a lower resolution
version in memory. The lower resolution version should match the size of the UI component that
displays it. An image with a higher resolution does not provide any visible benefit, but still takes up
precious memory and incurs additional performance overhead due to additional on the fly scaling.
This lesson walks you through decoding large bitmaps without exceeding the per application
memory limit by loading a smaller subsampled version in memory.

Read Bitmap Dimensions and Type


The BitmapFactory class provides several decoding methods
(decodeByteArray(), decodeFile(), decodeResource(), etc.) for creating aBitmap from various
sources. Choose the most appropriate decode method based on your image data source. These
methods attempt to allocate memory for the constructed bitmap and therefore can easily result in

an OutOfMemory exception. Each type of decode method has additional signatures that let you
specify decoding options via the BitmapFactory.Options class. Setting
the inJustDecodeBounds property totrue while decoding avoids memory allocation,
returning null for the bitmap object but setting outWidth, outHeight and outMimeType. This
technique allows you to read the dimensions and type of the image data prior to construction (and
memory allocation) of the bitmap.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;

To avoid java.lang.OutOfMemory exceptions, check the dimensions of a bitmap before decoding it,
unless you absolutely trust the source to provide you with predictably sized image data that
comfortably fits within the available memory.

Load a Scaled Down Version into Memory


Now that the image dimensions are known, they can be used to decide if the full image should be
loaded into memory or if a subsampled version should be loaded instead. Here are some factors to
consider:

Estimated memory usage of loading the full image in memory.

Amount of memory you are willing to commit to loading this image given any other memory
requirements of your application.

Dimensions of the target ImageView or UI component that the image is to be loaded into.

Screen size and density of the current device.

For example, its not worth loading a 1024x768 pixel image into memory if it will eventually be
displayed in a 128x96 pixel thumbnail in anImageView.
To tell the decoder to subsample the image, loading a smaller version into memory,
set inSampleSize to true in your BitmapFactory.Optionsobject. For example, an image with
resolution 2048x1536 that is decoded with an inSampleSize of 4 produces a bitmap of
approximately 512x384. Loading this into memory uses 0.75MB rather than 12MB for the full image
(assuming a bitmap configuration of ARGB_8888). Heres a method to calculate a sample size value
that is a power of two based on a target width and height:

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;
}

Note: A power of two value is calculated because the decoder uses a final value by rounding down
to the nearest power of two, as per theinSampleSize documentation.
To use this method, first decode with inJustDecodeBounds set to true, pass the options through
and then decode again using the newinSampleSize value and inJustDecodeBounds set to false:
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);
}

This method makes it easy to load a bitmap of arbitrarily large size into an ImageView that displays
a 100x100 pixel thumbnail, as shown in the following example code:

mImageView.setImageBitmap(
decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));

You can follow a similar process to decode bitmaps from other sources, by substituting the
appropriate BitmapFactory.decode* method as needed.
PreviousDisplaying

Bitmaps Efficiently NextProcessing Bitmaps Off the UI

Thread
Get news & tips SIGN UP FOR THE NEWSLETTER

Blog Support
ANDROID DEVELOPERS ON YOUTUBE ANDROID DEVELOPERS ON
GOOGLE+ ANDROID DEVELOPERS ON TWITTER

Except as noted, this content is licensed under Creative Commons Attribution 2.5. For details and
restrictions, see the Content License.
About Android Auto TV Wear Legal

This site uses cookies to store your preferences for site-specific language and display options.

Вам также может понравиться