Android Bitmap Loading for Efficient Memory Usage

Load a Bitmap from Resources Correctly

When handling bitmaps it is not long before Android developers come across the error “java.lang.OutOfMemoryError: bitmap size exceeds VM budget“. This usually occurs when the bitmaps are large (several megabytes uncompressed),  or running the code on older devices, or trying to load lots of bitmaps. This occurs because Android was design for mobile devices with limited resources, including memory, and bitmaps can require large amounts of memory. Despite Android not dealing with multi-megabyte bitmap loading automatically it can still be done. Instead of loading the whole bitmap a reduced resolution version is loaded (via a technique called subsampling). Android bitmap loading is achieved via the BitmapFactory class. The Options settings passed to the class can reduce the size of the bitmap, saving on memory usage.

Bitmaps can be BIG but Android Screens are Small

A digital image from a camera can be between 5 and 18 megapixels (MP) in size, depending upon the camera or device. This is the uncompressed size. The actual file storing the image, usually a JPEG file, is smaller than the displayed image because of compression. High end cameras can produce 20 MP or higher images. A 5 MP image can have a resolution of 2560×1920, that is greater than high definition (HD) television at 1920×1080, and bigger than the resolution of the Goggle Nexus 10 tablet device at 2560×1600. What about a 18 MP image? A size of 5184×3456!  A Nexus 5 phone has a HD screen, so why load more than 2 MPs of data if the screen can only display a maximum of 2 MPs. By using subsampling the huge photo image being viewed on the Android device only consumes as much memory as required to display it, 2 MP for a HD resolution screen. This saves precious App memory and reduces the possibility of out of memory errors. Here’s an example of loading large bitmaps on different Android devices. A 1000×1000 placeholder image was loaded into an ImageView  and the App run on two devices. One with a HVGA, 320×480, screen and another with a QVGA, 240×320 screen.

Android Bitmap on Different Screens

On the HVGA screen the 1000×1000 image is shown at 320×320, on the QVGA screen it is shown at 240×240. So the one million pixel image only requires a hundred thousand or sixty thousand pixels for actual viewing on these devices. Loading only the required size for display makes sense. On the Android Developers website there is an article on Managing Your App’s Memory and in the section Avoid wasting memory with bitmaps it states: “When you load a bitmap, keep it in RAM only at the resolution you need for the current device’s screen, scaling it down if the original bitmap is a higher resolution.

Android Bitmap Loading Code from the Developer Site

There is a series of lessons on the Android Developers site called Displaying Bitmaps Efficiently that deal with correctly loading, caching and processing bitmaps. When processing multiple large bitmaps it needs to be done away from the User Interface (UI) thread using AsyncTask, with the use of caching when appropriate. There is a sample App for the lessons, DisplayingBitmaps.zip, for Android Studio, though the code can be used in Eclipse if that is your preferred development platform. The example App was previously called Bitmap Fun from BitmapFun.zip. The basic steps in loading a large bitmap are:

  1. Determine the required size (from a known size or determining the size of the target View).
  2. Use the BitmapFactory class to get the bitmap’s size (set inJustDecodeBounds in BitmapFactory.Options to true).
  3. Using 1. and 2. calculate the subsampling value (a multiple of 2) and pass it to the BitmapFactory.Options setting inSampleSize.
  4. Use the BitmapFactory to load a reduced size bitmap.

The following section takes the code from the Android Developers article Displaying Bitmaps Efficiently to provide an example App performing the steps listed above.

Sample Code to Load an Android Bitmap from a Large Resource Image

J. M. W. Turner The Fighting Temeraire A large bitmap is needed. You may be reading this because you have a very large bitmap causing out of memory errors. Here a large image of a Turner painting is used. The image size is 5684×4226, a 24 MP image! You can grab the image from Wikimedia Commons, it is available in several sizes.

An Android App project was created in Eclipse. The large Turner image was added to the project in a folder called drawable-nodpi under the res folder. A large placeholder image (large enough to match the screen width) was also added to the folder. It can be generated from Placeholder Graphic at openclipart.org. The layout is just an ImageView with a Button below it:

Here’s the code for the App:

And the App in action:

Large Android Bitmap Loading

Using a Open Source Library to Manage Large Bitmap Loading in Android

This code is good for a single bitmap, but the Android Developers article goes on to talk about caching and background loading. One way of achieving this is to use an existing implementation, such as provided in the Display Bitmaps sample or existing libraries that support large bitmap loading with caching, including android-query (AQuery),  Android Volley for loading images over networks and Android Universal Image Loader.

Related Article

How to Get a View Size in Android

How to Set a Color In Android

Changing Colors in Android and Naming Them for Convenience

An Android color is a 32-bit integer value consisting of four eight bit parts, ARGB. The four parts are the amount of red, green and blue that is in the color, plus how opaque (see through) is the color, which is called the alpha value, the lower the alpha value the more transparent the color appears. (Note that in the United Kingdom color is spelt colour.)

The alpha value is the highest (first) byte in the 32-bit value followed by the red, then green and finally the blue byte. Hence it is referred to as an ARGB value with each letter representing the type and order of the byte. This format allows for easy representation as a hexadecimal number in Java:

The three byes representing the color values provide over 16 million color possibilities in Android (256 x 256 x 256 = 16,777,216). A color depth better than the human eye (stated in the Wikipedia article). Plus all these colors can range from transparent, 0, to opaque, 255.

Named Color Resources in Android

To help with handling colors in Android they can be made into a resource for easy of reuse. Either open an existing resource file or create a new one. For example in Eclipse with a Android project open select the res/values folder. Then use the File menu (or the context menu on the values folder) to add an Android XML File. Give the file a name, e.g. colors.xml and add a color element:

Use getColor() to read the color value from the resource.

If the color is solid (full alpha value) then the color resource can leave the alpha value out. Though for clarity and future maintenance it is wise to be explicit and always define all four parts of an Android color: Continue reading

Context Menu Example for Android

Take Your First Steps in Implementing Context Menus in Android

In this tutorial we provide an Android context menu example, using the aptly named ContextMenu class. On a Windows PC system the context menu is sometimes referred to as the right-click menu. (Though using this term is no recommended in case the user is left handed and has switched the mouse, in which case the context menu requires the left-click!)

Android Calendar Context MenuA context menu is a menu of options that apply to the item immediately under the pointer (mouse or finger). For example in the Android Calendar the context menu can be used to add an event to the diary, for the selected hour press and hold until the menu appears. The parts required to implement a simple context menu are:

  1. Define the menu captions, usually in a string resource file.
  2. Define the menu layout in an XML file.
  3. Tell Android a View is using a context menu.
  4. When the context menu is requested show it.
  5. React to the selected menu item.

The example code presented here is going to call the setColorFilter method of an ImageView using a context menu. This will be used to add a basic image effect to a bitmap graphic by applying a red, blue or green filter. In this tutorial we are assuming that you have a working project in Eclipse to use as a base. If not see the article Displaying a Bitmap in Android to generate one. Continue reading

Displaying a Bitmap in Android

Use an ImageView to Show a Raster Graphic

Showing a bitmap image, such as a Portable Network Graphics (PNG) or JPEG file, in an Android application (App) is easy. In this tutorial we show you how. It is assumed you are programming in Java using the Android SDK from within the Eclipse Integrated Development Environment (IDE). For PC users starting out in Android Java development see Set Up Windows for Android Development to prepare your development environment.

The ImageView class can be used and pointed at a bitmap stored under one of the drawable folders in the res project folders. Let us start by creating a very basic App project that will contain the ImageView and bitmap to display. If you do not know how to create a basic Android project in Eclipse see the article Your First Android Program. With Eclipse open select the File menu then New and Android Application Project. In the New Android App wizard the fields are set as follows:

  • Application Name – Bitmap
  • Project Name – Bitmap
  • Package Name – biz.tekeye.bitmap
  • Build SDK – Android 4.1 (API 16)
  • Minimum Required SDK – API 3: Android 1.5 (Cupcake) – or the lowest one installed
  • Create custom launcher icon – unchecked
  • Mark this project as a library – unchecked
  • Create project in Workspace – checked

Simple Android App Screen Open in EclipsePress the Next button. Create Activity should be checked and BlankActivity selected. Press the Next button again. On the New Blank Activity screen leave the fields as default and press Finish. The Bitmap project will be created and the App’s initial screen will load in the graphical designer. Continue reading

ImageButton Background with Shape Drawable

In this tutorial a background is set on an ImageButton to change its appearance. The article also shows how that appearance can be easily changed without the need to edit the button’s image. To follow this example the Eclipse Integrated Development Environment (IDE) is required. If your computer is not configured for developing Apps using Eclipse see Set Up Windows for Android Development. In Eclipse use the File menu and select New then Android Project. Fill in the Project Name, here Image Button is used. Click Next and select the build target from the installed APIs, e.g. Android 1.5, any of the installed APIs will work and it can be changed later if required. Click Next and enter the Package Name in the required format, e.g. biz.tekeye.imagebutton, leave Create Activity checked with the default Activity name, click Finish.

Green Tick Icon Android FormatA graphic is required for use with the ImageButton. Here a couple of buttons will be used one to show a red cross and another a green tick, with the images taken from the Open Clip Art Library, a good source of free graphics. You may have your own images to use.

Red Cross Icon in Android FormatTo see how images from the Open Clip Art Libray can be converted into PNGs see the article Android Launcher Icons Using Inkscape or Free Android Icons Using OpenClipArt.org and Paint.NET. The images are also on our Android Graphic Resources page with a Zip file available for importing directly into a project. See Move Android Code Between PCs Running Eclipse for instructions on importing from Zip (archive) files. Add the required images to the project’s res\drawable folder. Continue reading

High Resolution App Icon for Google Play Publishing

When it comes to publishing your newly created Android App you will need to provide some graphics for use on the information page for the App in the Google Play (formerly Android Market) store. Information on the types of graphics required can be found on the Google Play Graphics Assets for your Application web page, or in our summary article. One of the required graphics is the High Resolution Application Icon, this is a 512×512 32-bit Portable Network Graphics (PNG) file. The alpha channel is allowed therefore the actual visible image can be smaller, e.g. occupying 470×470 of the 512×512, if a drop shadow or border space was required. The article Android Launcher Icons Using Inkscape showed how the High Resolution Application Icon can be generated from the same Inkscape image file as the App’s launcher icon. This tutorial is going to take the same image and add a rounded rectangle background to give the image a border and button appearance.

A Cup of CoffeeTo follow this example Inkscape needs to be installed and the Scalar Vector Graphics (SVG) file of the Cup of Coffee image available. If Inkscape is not installed get it from http://inkscape.org. The tutorial for the Cup of Coffee image is at http://vector.tutsplus.com/tutorials/illustration/creating-a-coffee-cup-with-inkscape/, alternatively download it from OpenClipArt.org. Open the image in Inkscape. To manipulate the entire image as a single entity group any component parts together. This involves selecting all the component parts (if not already grouped) with the Select All option of the Edit menu (or Ctrl-A) and selecting the Group command from the Object menu (or Ctrl-G).

Inkscape Create Rectangle ToolSelect the Create rectangles and squares tool. Click and drag from the top left of the image down to the bottom right, while holding down the Ctrl key to draw a square over the image. This is the basis for the background and it will be moved below the image when the border and colors have been set.

Drag Circles to Make Rounded CornersDrag one of the circles at the top right to create rounded corners on the square. Hold down the Ctrl key while dragging to make the corner radii equal on the vertical and horizontal. With the basic rounded corner square box drawn the next steps are to determine whether it requires a border (and if so how wide), choose any required colors and set other effects like filters or gradients.

Open Edit Objects ColorsA border can be applied by enlarging the stroke used to draw the square and giving it a different color from the squares fill color. With the square selected open the Fill and Stroke dialog by clicking the Edit Objects… icon on the Controls bar (or Shift-Ctrl-F).

Inkscape Fill and Stroke DialogOn the Fill and Stroke dialog there are three tabs to access settings. The settings for color, gradient, blur and opacity for both fill and stroke can be changed. The stroke style can be changed, which includes the width. For this graphic the rounded square will have a border color different from the fill.

Choose two colors for the fill and stroke, for example set the fill to Teal (0x008080 RGB) and the stroke to Navy (0x000080 RGB). On the Stroke style tab set the Width to 20 px (pixels). The rounded square can be made more attractive by using a gradient or adding a filter, there are lots of predefined filters that can be used.

(Select Color from PaletteNote that colors can also be set via the palette bar towards the bottom of Inkscape. If it cannot be seen use the Show/Hide option on the View menu and select Palette.)

Object Width in InkscapeAt this stage a colored square with a border has been drawn over the coffee cup image. Before applying a filter to the square to make it more attractive the underlying document size will be set to make exporting the PNG easier. The final document needs to be square to support the correct exporting. With the rounded square selected make sure the width and height are equal using the W (width) and H (height) boxes on the toolbar (the width and height may be slightly out, if so edit the values to make them equal). The values do not need to be the same as the final icon size. The correct size is generated when the PNG file is exported. The width and height are the current object size and can be much larger or smaller than the final image. This is because Inkscape manipulates images as vector files which scale without loss of detail. After checking the squares dimensions open the Document Properties dialog via the File menu. With the square selected click the Resize page to drawing or selection button and ensure that the Show page border checkbox is set (so you can see that the document matches the square.

Inkscape Lower SelectionWith the square selected use the Filters menu to apply an effect. Here the Button filter is applied from the Bevels filter option. (You could choose a different filter and also modify filter properties. Experiment with filters on another image to see what effects are possible. Note that some filters use a lot of processing power so may update the image slowly on older PCs). With the work on the rounded square completed make sure it is selected and click the Lower selection to bottom toolbar button (or use the End key or access the option via the Object menu).

Coffee Cup Button in InkscapeWith the coffee cup visible again select it, position it centrally (use the drag arrows to make any size adjustments). The final image is then ready for export.

Open the Export Bitmap dialog from the File menu. In the Width and Height boxes under the Bitmap size option enter 512 (ignore the dpi boxes, they will change automatically). Browse to a location and enter a Filename. Press the Export button. The image is now available for uploading to the Product Details page when the App is ready for publishing.

The principles covered in this article also apply to the generation of the other graphic files required for App publishing. Inkscape can be used to design those file before exporting them to PNG files at the correct size. See also the article Grabbing an Android Device Screenshot on how to get hold of the screenshot images needed to publish an App.

Google Play Publishing Graphics Checklist

You like your Android Phone or Tablet, it gives you easy portable computing with access to thousands of programs that cover almost any subject. Almost. That App that you wanted doesn’t exist so you’ve invested some time and energy and made it yourself. Now you’d like to publish it so that others can use it, and maybe make a little money on the side. Unfortunately you’ll need to break out the creative talents again and come up with some promotional graphics, because your App will not be listed on Google Play (formerly Android Market) unless those graphics are available. The following table lists the graphic and media images you will need to produce to publish on Google Play.

Media Assets Required for Google Play App Publishing
Item Type Opt. Size Alpha Padding
2 to 8 Screenshots 24-bit PNG/JPG No 320×480 or 480×800 or 480×854 No No
Large App Icon 32-bit PNG No 512×512 (1024KB max.) Yes Allowed
Promo Image 24-bit PNG/JPG Yes 180×120 No No
Feature Image 24-bit PNG/JPG Yes 1024×500 (924×400 useable) No Yes
YouTube Video Link URL Yes N/A N/A N/A

Notes:

  • Provide every asset for a professional app listing, even those that are optional.
  • PNG is a Portable Networks Graphics file, file extension normally .png.
  • JPG file extension is normally .jpg or .jpeg and is a Joint Photographics Expert Group graphics format.
  • All graphics sizes are give as X pixels times Y pixels (i.e. 320×480 is 320 pixels wide by 480 pixels high).
  • Alpha determines whether or not the alpha channel is support for the given image being used.
  • Do not put a border around the edge of any graphics.
  • Use large fonts, bright contrasting colors and crisp designs that are not overly detailed. Particularly for the Feature Image which may be scaled down.

See the article High Resolution App Icon for Google Play Publishing for a tutorial on generating the 512×512 image.

See the article Grabbing an Android Device Screenshot for information on generating the screenshots required.

The Google web page Graphic Assets for your Application has further details.

Grabbing an Android Device Screenshot

Android developers need to be able to grab a screenshot of their App running on a device or the emulator. This is because when the App is published on Google Play (previously known as Android Market) one of the requirements is at least two screenshots. The ability to take a screenshot helps with the production of a website to support the App (online user guides, manuals, training and quick start guides). There is also the production of marketing materials and good old fashioned printed user guides or manuals.

It is most likely that the screen capture will be done during the final testing phases of the App on a developers computer. The App will be running on a Android Virtual Device (AVD) configuration or on a device physically tethered to the computer, usually connected via a USB cable. This tutorial explains how easy it is to capture the screen for an Android device from within the Eclipse programming environment. If you have a App project handy start up Eclipse now and give it ago. Alternatively install Eclipse (see this article) and try it with one of our example projects.

Open Perspective HintExecute the project so that it is running on an AVD or physical device. In the upper right hand corner of Eclipse click the Open Perspective button, or use the Eclipse Window menu and select Open Perspective. This will open a menu with several options.

DDMS Menu Option via Open PerspectiveFrom the Open Perspective menu chose the Dalvik Debug Monitor Server (DDMS) entry. The DDMS is provided with the Software Development Kit (SDK) and is available from Eclipse when the Android Development Tools (ADT) plugin is installed. Continue reading

Example List of Android Device Screen Resolutions and Sizes

The success of Android as a mobile device Operating System (OS) has resulted in a large variety of screen sizes and resolutions. Here is provided a list of example devices to show that variation.

Portrait v LandscapeIn the following table it is assumed that the device is held in portrait orientation. As such the width in pixels is the X-axis and the length or height in pixels is the Y-axis. Obviously that swaps when the device is held in landscape orientation. Android has support for both orientations so that a correctly programmed App will work no matter which way you hold the device. If you need to understand about pixels see the article How Computer Screens and Printers Show Images. The total number of pixels in a screen is the number in the x-axis multiplied by the number in the y-axis. The more pixels for each square inch (or centimetre) of display the sharper any images will be displayed (provided those images are at a high resolution).

For an explanation of the Acronym see the article Screen Resolution Names. The Size column next to each device is the diagonal measurement for the device screen in inches. This table illustrates that screens with the same resolution can be different sizes.

Example Andriod Screen Sizes and Resolutions
# Pixels X Y ACRONYM Device Example 1 Size Device Example 2 Size
76800 240 320 QVGA ZTE Tureis 2.6 Samsung Galaxy Fit (GT-S5670 ) 3.3
96000 240 400 WQVGA400 Samsung Galaxy Apollo 3.2 Archos 32 Internet Tablet 3.2
153600 320 480 HVGA HTC ChaCha 2.6 HTC Explorer 3.2
230400 360 640 nHD Dell Aero 3.5 Dell Mini 3ix 3.5
307200 480 640 VGA Motorola Pro+ MB632 3.1 Motorola Admiral 3.1
384000 480 800 WVGA800 Google Nexus One 3.7 Dell Streak 7 7
409920 480 854 WVGA854 Sony Xperia Ray 3.3 Archos 43 Internet Tablet 4.3
480000 600 800 SVGA Elonex eTouch 702ET 7 Pandigital SuperNova 8
491520 480 1024 UWVGA Acer Iconia Smart S300 4.8 Sony Tablet P 5.5
518400 540 960 qHD Motorola Atrix 4 HTC Vivid 4.5
614400 640 960 DVGA Sharp IS03 3.5 iPhone 4S 3.5
614400 600 1024 WSVGA Amazon Kindle Fire 7 Archos 101 Internet Tablet 10.1
786432 768 1024 XGA Archos 80 G9 8 Malata T8 9.7
921600 720 1280 WXGA720, HD, 720p Galaxy Nexus (GT-i9250) 4.6 Sony Xperia S 4.3
983040 768 1280 WXGA Ramos W15 8 LG Optimus PAD (V900) 8.9
1024000 800 1280 WXGA800 Samsung Galaxy Note (GT-N7000) 5.3 Motorola Xoom 2 10.1

The iPhone 4S is shown in the table for comparision purposes, see the DVGA line, it is not an Android phone. Note a Full High Definition (FHD) or 1080i/1080p screen is 1080×1920 which is 2,073,600 pixels. Despite the wide variation in resolutions and screen sizes the Android OS and its Software Development Kit (SDK) caters for all of them.