nullnullLoading Large Bitmaps Efficiently 有效的处理较大的位图

首先声明,我是一个菜鸟。一下文章中出现技术误导情况盖不负责

    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. http://blog.csdn.net/sergeycao

    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 anOutOfMemory exception. Each type of decode method has additional signatures that let you specify decoding options via theBitmapFactory.Options class. Setting the inJustDecodeBounds property totrue while decoding avoids memory allocation, returning null for the bitmap object but settingoutWidth, 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, it’s 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, setinSampleSize to true in your BitmapFactory.Options object. For example, an image with resolution 2048x1536 that is decoded with aninSampleSize 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 ofARGB_8888). Here’s a method to calculate a the sample size value 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) {
        if (width > height) {
            inSampleSize = Math.round((float)height / (float)reqHeight);
        } else {
            inSampleSize = Math.round((float)width / (float)reqWidth);
        }
    }
    return inSampleSize;
}

    Note: Using powers of 2 for inSampleSize values is faster and more efficient for the decoder. However, if you plan to cache the resized versions in memory or on disk, it’s usually still worth decoding to the most appropriate image dimensions to save space.

    To use this method, first decode with inJustDecodeBounds set totrue, pass the options through and then decode again using the new inSampleSize value and inJustDecodeBounds set tofalse:

    

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 appropriateBitmapFactory.decode* method as needed.

文章结束给大家分享下程序员的一些笑话语录: 问路
有一个驾驶热气球的人发现他迷路了。他降低了飞行的高度,并认出了地面 上的一个人。他继续下降高度并对着那个人大叫,“打扰一下,你能告诉我我 在哪吗?”
下面那个人说:“是的。你在热气球里啊,盘旋在 30 英尺的空中”。
热气球上的人说:“你一定是在 IT 部门做技术工作”。
“没错”,地面上的人说到,“你是怎么知道的?”
“呵呵”,热气球上的人说,“你告诉我的每件事在技术上都是对的,但对都没 有用”。
地面上的人说,“你一定是管理层的人”。
“没错”,热气球上的人说,“可是你是怎么知道的?”
“呵呵”,地面上的那人说到,“你不知道你在哪里,你也不知道你要去哪,你 总希望我能帮你。你现在和我们刚见面时还在原来那个地方,但现在却是我 错了”。

你可能感兴趣的:(bitmap)