如何优化加载大位图(BitmapFactory使用系列)
2014-03-21 11:23
603 查看
Loading Large Bitmaps Efficiently
如何优化加载大位图
Images come in all shapes and sizes.In many cases they are larger than required for a typical application userinterface (UI). For example, the system Gallery application displays photostaken using your
Android devices's camera which are typically much higherresolution than the screen density of your device.
Given that you are working with limited memory, ideally you onlywant to load a lower resolution version in memory. The lower resolution versionshould match the size of the UI component that displays it. An image with ahigher resolution
does not provide any visible benefit, but still takes upprecious memory and incurs additional performance overhead due to additional onthe fly scaling.
This lesson walks you through decoding large bitmaps without exceedingthe per application memory limit by loading a smaller subsampled version inmemory.
图片有各种形状和大小。在很多情况下,这些图片的大小超过我们应用程序的需要,例如用手机拍摄的图片。
假如,你的应用程序只有有限的内存容量,最理想的做法是在内存中加载低分辨率的图像版本。低版本的图像需要适应设备屏幕的大小。一张高分辨率的图片不仅不会改善显示质量,而且还会影响应用程序的性能。
这个课程将讲述如何将一些大的位图压缩成少于应用程序使用内存容量的小图片。
The
providesseveral decoding methods (
etc.)for creating a
various sources.Choose the most appropriate decode method based on your image data source.These methods attempt to allocate memory for the constructed bitmap andtherefore can easily result in an
Each typeof decode method has additional signatures that let you specify decodingoptions via the
Setting the
to
the bitmap objectbut setting
Thistechnique allows you to read the dimensions and type of the image data prior toconstruction (and memory allocation) of the bitmap.
BitmapFactory类提供了几个解码方法能够从各种源文件中创建Bitmap对象,例如(, int, int, android.graphics.BitmapFactory.Options)]decodeByteArray(), decodeFile(),decodeResource()等)。我们需要根据图片的格式选择合适的解码方法。这些方法都尝试去为创建好的Bitmap对象分配内存,但是这样做会很容易导致
如下代码所示:
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;[/code]
To avoid
trust thesource to provide you with predictably sized image data that comfortably fitswithin the available memory.
为了避免
Now that the image dimensions are known, they can be used todecide if the full image should be loaded into memory or if a subsampledversion should be loaded instead. Here are some factors to consider:
· Estimated memory usage of loading the fullimage in memory.
· Amount of memory you are willing to commit toloading this image given any other memory requirements of your application.
· Dimensions of the target
UIcomponent that the image is to be loaded into.
· Screen size and density of the currentdevice.
4、
To tell the decoder to subsample theimage, loading a smaller version into memory, set
your
For example,an image with resolution 2048x1536 that is decoded with an
4 produces abitmap of approximately 512x384. Loading this into memory uses 0.75MB ratherthan 12MB for the full image (assuming a bitmap configuration of
Here’sa method to calculate a sample size value that is a power of two based on atarget width and height:
Note: A power of two valueis calculated because the decoder uses a final value by rounding down to thenearest power of two, as per the
To use this method, first decode with
to
and
to
This method makes it easy to load a bitmap of arbitrarily largesize into an
displays a100x100 pixel thumbnail, as shown in the following example code:
You can follow a similar process to decode bitmaps from othersources, by substituting the appropriate
as needed.
如何优化加载大位图
Images come in all shapes and sizes.In many cases they are larger than required for a typical application userinterface (UI). For example, the system Gallery application displays photostaken using your
Android devices's camera which are typically much higherresolution than the screen density of your device.
Given that you are working with limited memory, ideally you onlywant to load a lower resolution version in memory. The lower resolution versionshould match the size of the UI component that displays it. An image with ahigher resolution
does not provide any visible benefit, but still takes upprecious memory and incurs additional performance overhead due to additional onthe fly scaling.
This lesson walks you through decoding large bitmaps without exceedingthe per application memory limit by loading a smaller subsampled version inmemory.
图片有各种形状和大小。在很多情况下,这些图片的大小超过我们应用程序的需要,例如用手机拍摄的图片。
假如,你的应用程序只有有限的内存容量,最理想的做法是在内存中加载低分辨率的图像版本。低版本的图像需要适应设备屏幕的大小。一张高分辨率的图片不仅不会改善显示质量,而且还会影响应用程序的性能。
这个课程将讲述如何将一些大的位图压缩成少于应用程序使用内存容量的小图片。
ReadBitmap Dimensions and Type
读取位图的尺寸和类型The
BitmapFactoryclass
providesseveral decoding methods (
, int, int, android.graphics.BitmapFactory.Options)]decodeByteArray(),
decodeFile(),
decodeResource(),
etc.)for creating a
Bitmapfrom
various sources.Choose the most appropriate decode method based on your image data source.These methods attempt to allocate memory for the constructed bitmap andtherefore can easily result in an
OutOfMemoryexception.
Each typeof decode method has additional signatures that let you specify decodingoptions via the
BitmapFactory.Optionsclass.
Setting the
inJustDecodeBoundsproperty
to
truewhile decoding avoidsmemory allocation, returning
nullfor
the bitmap objectbut setting
outWidth,
outHeightand
outMimeType.
Thistechnique allows you to read the dimensions and type of the image data prior toconstruction (and memory allocation) of the bitmap.
BitmapFactory类提供了几个解码方法能够从各种源文件中创建Bitmap对象,例如(, int, int, android.graphics.BitmapFactory.Options)]decodeByteArray(), decodeFile(),decodeResource()等)。我们需要根据图片的格式选择合适的解码方法。这些方法都尝试去为创建好的Bitmap对象分配内存,但是这样做会很容易导致
OutOfMemory的异常。每种类型的解码方法,你都需要通过
BitmapFactory.Options类来指定参数值。将
inJustDecodeBounds参数值设定为true的时候,解码过程中将不为对象分配内容,但是会将图片的尺寸等信息通过
BitmapFactory.Options对象的
outWidth,
outHeight和
outMimeType值反馈。
如下代码所示:
BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
//解码完成后,[code]outWidth,
outHeight和
outMimeType值将包含图片的尺寸大小
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;[/code]
To avoid
java.lang.OutOfMemoryexceptions, check thedimensions of a bitmap before decoding it, unless you absolutely
trust thesource to provide you with predictably sized image data that comfortably fitswithin the available memory.
为了避免
java.lang.OutOfMemory异常,需要在真正解码之前,通过上面代码描述的方法获取图片的真实尺寸。
Load aScaled Down Version into Memory
将一个压缩版本加载到内存中Now that the image dimensions are known, they can be used todecide if the full image should be loaded into memory or if a subsampledversion should be loaded instead. Here are some factors to consider:
至此,你可以通过图片的尺寸来觉得是否使用一个一个压缩的版本来加载到内存中。下面有一些因素,你需要考虑到:
· Estimated memory usage of loading the fullimage in memory.
· Amount of memory you are willing to commit toloading this image given any other memory requirements of your application.
· Dimensions of the target
ImageViewor
UIcomponent that the image is to be loaded into.
· Screen size and density of the currentdevice.
1、
预估加载整个图片后,需要占用的内存大小;
2、
应用程序关于加载图片时使用内存大小的需求;
3、
存放图片的
ImageView
或者
UI
组件的尺寸;
4、
屏幕大小。
To tell the decoder to subsample theimage, loading a smaller version into memory, set
inSampleSizeto
truein
your
BitmapFactory.Optionsobject.
For example,an image with resolution 2048x1536 that is decoded with an
inSampleSizeof
4 produces abitmap of approximately 512x384. Loading this into memory uses 0.75MB ratherthan 12MB for the full image (assuming a bitmap configuration of
ARGB_8888).
Here’sa method to calculate a sample size value that is a power of two based on atarget width and height:
为了能够将图片压缩,你需要将
inSampleSize
的值设定为
true
。下面是计算压缩比例的例子:
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 valueis calculated because the decoder uses a final value by rounding down to thenearest power of two, as per the
inSampleSizedocumentation.
To use this method, first decode with
inJustDecodeBoundsset
to
true, pass theoptions through and then decode again using the new
inSampleSizevalue
and
inJustDecodeBoundsset
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 largesize into an
ImageViewthat
displays a100x100 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 othersources, by substituting the appropriate
, int, int, android.graphics.BitmapFactory.Options)]BitmapFactory.decode*method
as needed.
相关文章推荐
- 如何优化加载大位图(BitmapFactory使用系列)
- Android使用BitmapFactory.Options解决加载大图片内存溢出问题
- Android使用BitmapFactory.Options解决加载大图片内存溢出问题
- Android使用BitmapFactory.Options解决加载大图片内存溢出问题
- Bitmap加载大图优化之位图重采样与Bitmap缓存Lru算法分析
- Android使用BitmapFactory.Options解决加载大图片内存溢出问题
- BitmapFactory.decodeByteArray如何使用
- Android使用BitmapFactory.Options解决加载大图片内存溢出问题
- Android使用BitmapFactory.Options解决加载大图片内存溢出问题
- Yelp app是如何使用Glide优化图片加载的
- 如何使用js懒加载图片|如何使用jquery.lazyload.js|网页优化|如何提高网页加载速度
- 如何优化使用C6000系列C64x的Cache--原理,Cache种类和优化策略
- Android使用BitmapFactory.Options解决加载大图片内存溢出问题
- Yelp app是如何使用Glide优化图片加载的
- TensorFlow学习系列(五):如何使用队列和多线程优化输入管道
- 【Android开发经验】Bitmap高效显示系列——如何有效的加载大尺寸Bitmap
- 如何使用Bitmaputils加载图片
- BitmpaFactory和BitmapFactory.Options详解及优化解码图片时使用的内存
- Android Bitmap大量使用不产生OOM之“加载大图片资源优化”
- Android使用BitmapFactory.Options解决加载大图片内存溢出问题