Android Bitmap in-depth introduction (i)---Foundation

Source: Internet
Author: User

In Android app development, we often need to deal with pictures, and pictures a very troublesome problem is the use of memory is very large, often lead to oom, understand bitmap related information, different SDK version of the Android image processing changes, And some of the ways to optimize the processing of our normal development in the picture will be very helpful.

This article first introduces bitmap basic content, about pixels, storing information, and loading.

Pixel

Bitmap storage can be said to include two parts, pixels and long, wide, color and other descriptive information. Pixels are the most memory-intensive place in the bitmap, where the length and pixel bits are used to describe the image, and this information calculates the memory size occupied by the image's pixels. The specific API to bitmap is the following interfaces:

publicfinalintgetWidth()publicfinalintgetHeight()publicfinalgetConfig()

The

Config is an enumeration type that represents a picture pixel type, with a total of the following types: alpha_8 (1), rgb_565 (3), argb_4444 (4), argb_8888 (5); . Represents a picture of each pixel. In fact, the following two ways to get the values are equal:

int  B = 1 ; switch  (Bitmap.getconfig ())        {case  alpha_8:b = 1 ;    break ; case         Argb_4444:b = 2 ;    break ; case         Argb_8888:b = 4 ; break ;} int  bytes1 = bitmap.getwidth () * Bitmap.getheight () * b; int  bytes2 = Bitmap.getbytecount (); //interface from api12   

This is determined by the bitmap related parameters can calculate the number of pixels occupied by bitmap, in fact, we put in drawable inside the picture is already know the image of the length and width of the pixel composition, but directly on the outside of the Android image pixel count and the above code to calculate there will be a discrepancy. Because Android has scaled the image, this is related to the drawable location where you put the image.

We all know that there will be drawable-hdpi, drawable-xhdpi,drawable-xxhdpi and other directories in the Android resource directory. Each directory here will correspond to a density. Here's an example of the Bitmapfactory.decoderesource method loading bitmap:

BitmapFactory.Options options = new BitmapFactory.Options();Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test4, options);Log.i"options: " + options.inDensity"," + options.inTargetDensity);

Decoderesource is the Android internal to the resource load mode, here is not from the source above step by step introduction, it will eventually call Decoderesourcestream method, directly see Decoderesourcestream:

 Public StaticBitmapDecoderesourcestream(Resources Res, typedvaluevalue, InputStream is, Rect pad, Options opts) {if(opts = =NULL) {opts =NewOptions (); }if(Opts.indensity = =0&&value!=NULL) {FinalintDensity =value. density;if(density = = Typedvalue.density_default)        {opts.indensity = Displaymetrics.density_default; }Else if(Density! = Typedvalue.density_none)        {opts.indensity = density; }    }if(Opts.intargetdensity = =0&& Res! =NULL) {opts.intargetdensity = Res.getdisplaymetrics (). densitydpi; }returnDecodestream ( is, pad, opts);}

Options.indensity represents the default pixel density of the picture itself, Typedvalue will have a density that corresponds to which drawable directory the image is from, because each drawable directory (drawable-hdpi, DRAWABLE-XHDPI,DRAWABLE-XXHDPI) corresponds to a screen, and the screen has density,typedvalue density corresponding to Displaymetrics densitydpi, DENSITYDPI represents the number of pixels per foot. Options.intargetdensity is the densitydpi of the current phone screen, the final number of pixels is:

bytes = 原始图片宽*(options.inDensity/options.inTargetDensity)*原始图片长*(options.inDensity/options.inTargetDensity)*每个像素点位数
Storage and transport

Android images are not the same place to store in different SDK versions. Before 2.3 and 2.3, picture pixels were stored in native memory. Android memory is divided into Java heap and native memory. Android limits the maximum memory that each app can use. However, Android's memory limit is the Java heap and native memory, and the pixel data in the native area, the virtual machine can not automatically garbage collection, you must manually use Bitmap.recycle () to cause a very easy memory leak. Because Android device monitor can only see the memory changes in the Java heap, it is not easy to debug bitmap memory. For example, to create a new image in the app, you simply can't see the memory changes in the monitor.

Starting from 3.0 Android saves the picture in the Java heap, and when a new image is loaded, it can be immediately reflected from monitor. In addition, Java garbage collection mechanism can also be automatically recycled. Then after 4.0, the picture has some changes, that is, when the parcel transmission, when the picture is very large, it will use ASHMEM to carry out the transmission of the picture, specifically can see me this article Android4.0 after parcel transmission bitmap source analysis. In 6.0, the image of the storage has changed a lot, the bottom has been significantly increased the image to save Ashmem interface, specifically can see me this article Android6.0 bitmap storage and parcel transmission source analysis

Bitmapfactory

Bitmapfactory is used to load images, this class is mainly divided into three kinds of images loading, first take its API to look at:

     Public StaticBitmapDecoderesourcestream(Resources Res, typedvaluevalue, InputStream is, Rect pad, Options opts) Public StaticBitmapDecoderesource(Resources Res,intID, Options opts) Public StaticBitmapDecoderesource(Resources Res,intId Public StaticBitmapDecodebytearray(byte[] Data,intOffsetintLength, Options opts) { Public StaticBitmapDecodebytearray(byte[] Data,intOffsetintLength) { Public StaticBitmapDecodeFile(String PathName, Options opts) Public StaticBitmapDecodeFile(String pathName) Public StaticBitmapDecodestream(InputStream is, Rect outpadding, Options opts) Public StaticBitmapDecodestream(InputStream is) Public StaticBitmapDecodefiledescriptor(FileDescriptor fd, Rect outpadding, Options opts) Public StaticBitmapDecodefiledescriptor(FileDescriptor FD)

We look directly at the Nativedecode interface provided by Bitmapfactory:

    Private Static nativeBitmapNativedecodestream(InputStream is,byte[] storage, Rect padding, Options opts);Private Static nativeBitmapNativedecodefiledescriptor(FileDescriptor fd, Rect padding, Options opts);Private Static nativeBitmapNativedecodeasset(LongNativeasset, Rect padding, Options opts);Private Static nativeBitmapNativedecodebytearray(byte[] Data,intOffsetintLength, Options opts);

Bitmapfactory to file decode will be converted to InputStream Nativedecodestream to decode, resource will use Decode, And if Filedesciptor can be converted to native FD, it will decode through Nativedecodefiledescriptor, In addition ByteArray will directly use Nativedecodebytearray to decode. It is important to note that the resource decode,bitmapfactory will be set to the relevant parameters of option, and eventually the corresponding scaling, the size of the picture will be different from the original. specific content suggested to look at Bitmapfactory, understand the difference between each way, to be able to better use the interface, choose the time to adopt more efficient method.

Bitmapfactory.options

Let's take a look at the options class, we can use this parameter to do some processing on the image when loading, we have already said Indensity and intargetdensity. Look at the other parameters below.

Inpurgeable

The purpose of this parameter is to load the bitmap when the bitmap is needed, and to recycle the bitmap when it is not needed. In 4.1, with inpurgeable, the memory will not increase when the picture is loaded, but the memory is significantly increased without using inpurgeable to load the picture.

Insamplesize

This indicates the sample size, length and width will be multiplied by 1/insamplesize. Used to zoom out the picture so that the station occupies too much memory and is suitable for thumbnails.

Injustdecodebounds

This sets true to get the width length information for the picture. Here's an example:

BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;Bitmap bmp = BitmapFactory.decodeFile(path, options);// options.outWidth 和 options.outHeight就能够获取结果

This article primarily introduces BITMAP related basic information, bitmap,bitmapfactory and options classes, and Bitmap storage.

Android Bitmap in-depth introduction (i)---Foundation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.