Loading Large Bitmaps Efficiently高效加载大图(Android开发文档翻译一)

来源:互联网 发布:软件系统的性能指标 编辑:程序博客网 时间:2024/05/17 23:01

原文地址:http://developer.android.com/training/displaying-bitmaps/load-bitmap.html


注:我的英文水平确实有限,希望大家能够指出不足之处:——),建议多阅读官方文档,市场上很多书将思想讲的比较少,一来就是组件和熟悉。。。简直无语

我接下来写的关于Android的文档基本以翻译为主,原因有:1、个人能力有限,不想耽误童鞋们。。

我把我个人觉得相对重要的用红色标注了


Images come in all shapesand sizes. In many cases they are larger than required for a typicalapplication user interface (UI). For example, the system Gallery applicationdisplays photos taken using your Android devices's camera which are typicallymuch higher resolution than the screen density of your device.

图片有各种形状和大小。在很多场合下,对于一个典型的应用界面UI,大图往往都要比界面所需要的图片要大。比如,Gallery应用展示你设备上的相机拍摄的照片,这些照片比你的设备的屏幕密度要有更高的分辨率。

 

Given that you are workingwith limited memory, ideally you only want to load a lower resolution versionin memory. The lower resolution version should match the size of the UIcomponent that displays it. An image with a higher resolution does not provideany visible benefit, but still takes up precious memory and incurs additionalperformance overhead due to additional on the fly scaling.

假设你的内存有限,理想情况下你只是希望在内存中加载一个更低分辨率的版本。这个低分辨率版本的图片应该要匹配展示它的UI组件的大小。一个拥有高分辨率的图片不会提供任何看得到的好处,相反会占用宝贵的内存并且由于额外的缩放将引发额外的性能开销

 

 

This lesson walks youthrough decoding large bitmaps without exceeding the per application memorylimit by loading a smaller subsampled version in memory.

这个课程将引导你在不超过应用内存限制情况下,通过往内存中加载一个更小的子样本(我的理解是通过对大图进行抽样,做成一个小图)版本完成高效decode大图。

 

ReadBitmap Dimensions and Type

获取图片的尺寸和类型

 

The BitmapFactory class provides several decoding methods (decodeByteArray()decodeFile(),decodeResource(), etc.) for creating a Bitmap from various sources. Choose the most appropriate decodemethod based on your image data source. These methods attempt to allocatememory for the constructed bitmap and therefore can easily result in an OutOfMemory exception. Each type of decode method has additionalsignatures that let you specify decoding options via the BitmapFactory.Options class. Setting theinJustDecodeBounds property to true while decoding avoids memory allocation, returning null for the bitmap object but setting outWidthoutHeight and outMimeType. This technique allows you to read the dimensions and typeof the image data prior to construction (and memory allocation) of the bitmap.

 

BitmapFactory 类为从各种资源中创建Bitmap提供了几个编码的方式(decodeByteArray()decodeFile(),decodeResource(), etc.)你要根据你的图片资源选择最合适的编码方法。这些methods将为constructed bitmap分配内存,因而很容易引发outOfMemoryOOM)异常。每种编码方式都有一个额外的符号(signatures)让你通过BitmapFactory.Options 去指定decoding options。编码时(decoding)设置theinJustDecodeBounds属性为true来避免分配内存,同时返回null给bitmap 对象,但会产生 outWidthoutHeight and outMimeType.这几个值。这种技术允许你在构造(内存分配)bitmap之前去读取图片数据的尺寸和类型

给出实现代码:

BitmapFactory.Options options=newBitmapFactory.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, checkthe dimensions of a bitmap before decoding it, unless you absolutely trust the sourceto provide you with predictably sized image data that comfortably fits withinthe available memory

 

为了避免java.lang.OutOfMemory异常,在decoding bitmap之前获取它的尺寸,除非你确信你提供的资源已知image data 的大小,并且能够很好适应可用内存

 

Load aScaled Down Version into Memory

加载一个缩小的版本到内存中

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

·        Estimated memory usage of loading the fullimage in memory.

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

·        Dimensions of the target ImageView or UI componentthat the image is to be loaded into.

·        Screen size and density of the currentdevice.

现在你已经知道了图片的尺寸,他们能够用来确定是否是把原图加载进内存还是只是加载它的抽样版本(subsampled version),这里有几个因素你要考虑:

         估算加载原图到内存的用量

         在你的应用有其它的内存需求的条件下,给出你愿意给图片分配的内存大小

         目标ImageView或者是图片要加载到的UI组件的尺寸

         当前设备的屏幕大小和密度

 

For example,it’s not worth loading a 1024x768 pixel image into memory if it will eventuallybe displayed in a 128x96 pixel thumbnail in an ImageView.

To tell thedecoder to subsample the image, loading a smaller version into memory,set inSampleSize to true inyour BitmapFactory.Options object.For example, an image with resolution 2048x1536 that is decoded with aninSampleSize of 4produces a bitmap of approximately 512x384. Loading this into memory uses0.75MB rather than 12MB for the full image (assuming a bitmap configurationof ARGB_8888). Here’s amethod to calculate a sample size value that is a power of two based on atarget width and height:

比如,加载1024*768像素的图片到内存中但最后将在ImageView中展示成一个128*96的缩略图,这没啥子用。

 

要告诉decoder去抽样(subsample)图片,加载一个小尺寸版本的进入到内存中,需要在 BitmapFactory.Options 对象中设置. inSampleSize to true 。比如,一个图片分辨率为2048*1536,以inSampleSize 为4进行decode,那么最后将产生大约512*384分辨率的图片。加载它到内存中只需要0.75MB而不是对于全图的12MB(假设bitmap的编码方式为ARGB_8888),这里有一个方法来计算一个基于目标imgview的宽和高产生一个值为2的幂的sample size:

public static int calculateInSampleSize(
            BitmapFactory.Options options,int reqWidth,int reqHeight){
    // Raw heightand 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 keepsboth
        // height and width larger than the requested height and width.
        while ((halfHeight/ inSampleSize)> reqHeight
                && (halfWidth / inSampleSize)> reqWidth){
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

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

这个方法让其变地很容易去加载一个大图到一个展示100*100像素的缩略图的ImageView中。就想下面的代码显示的一样

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

You can follow a similarprocess to decode bitmaps from other sources, by substituting the appropriateBitmapFactory.decode* method as needed.

 

你能够按照一个相似的方法从其他资源中decode bitmap,通过把BitmapFactory.decode* 方法替换成你需要的


转载请注明出处:http://blog.csdn.net/storyofliu_yu

0 0
原创粉丝点击