在网上看到了一个文章,觉得挺好,又怕复制链接后什么时候网页给删了,就把全文给复制过来了,源网址是http://www.lephone.net/thread-1191-1-1.html

首先我们来介绍一下BitmapFactory.Options这个类,它是实现我们目标的关键。 ; P7 v" K; ~9 |5 V8 @
下面先看看它都有哪些成员
Fields
public Bitmap inBitmap If set, decode methods that take the Options object will attempt to reuse this bitmap when loading content.
public int inDensity The pixel density to use for the bitmap.
public boolean inDither If dither is true, the decoder will attempt to dither the decoded image.
public boolean inInputShareable This field works in conjuction with inPurgeable.
public boolean inJustDecodeBounds If set to true, the decoder will return null (no bitmap), but the out...
public boolean inMutable If set, decode methods will always return a mutable Bitmap instead of an immutable one.
public boolean inPreferQualityOverSpeed If inPreferQualityOverSpeed is set to true, the decoder will try to decode the reconstructed image to a higher quality even at the expense of the decoding speed.
public Bitmap.Config inPreferredConfig If this is non-null, the decoder will try to decode into this internal configuration.
public boolean inPurgeable If this is set to true, then the resulting bitmap will allocate its pixels such that they can be purged if the system needs to reclaim memory.
public int inSampleSize If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory.
public boolean inScaled When this flag is set, if inDensityand inTargetDensityare not 0, the bitmap will be scaled to match inTargetDensitywhen loaded, rather than relying on the graphics system scaling it each time it is drawn to a Canvas.
public int inScreenDensity The pixel density of the actual screen that is being used.
public int inTargetDensity The pixel density of the destination this bitmap will be drawn to.
public byte[] inTempStorage Temp storage to use for decoding.
public boolean mCancel Flag to indicate that cancel has been called on this object.
public int outHeight The resulting height of the bitmap, set independent of the state of inJustDecodeBounds.
public String outMimeType If known, this string is set to the mimetype of the decoded image.
public int outWidth The resulting width of the bitmap, set independent of the state of inJustDecodeBounds.
这个表格是从android sdk文档里摘出来的,简单看一下说明就明白是什么意思了。 6 n5 K; A4 m$ j4 C+ N
下面我们回到我们的主题上来:怎样获取图片的大小? 0 H8 F7 S# H% F. e9 `. p
思路很简单: ( C' jh4 ?; U; i4 r( I# f
首先我们把这个图片转成Bitmap,然后再利用Bitmap的getWidth()和getHeight()方法就可以取到图片的宽高了。

新问题又来了,在通过BitmapFactory.decodeFile(String path)方法将突破转成Bitmap时,遇到大一些的图片,我们经常会遇到OOM(Out Of Memory)的问题。怎么避免它呢?
这就用到了我们上面提到的BitmapFactory.Options这个类。 / l) j5 fe' L6 B
: c/ R' D' T/ Y+ F4 R& ]5 B; f5 X
BitmapFactory.Options这个类,有一个字段叫做 inJustDecodeBounds 。SDK中对这个成员的说明是这样的: 9 E( W( j2 @% h1 p9 k% `0 s4 [
If set to true, the decoder will return null (no bitmap), but the out...

也就是说,如果我们把它设为true,那么BitmapFactory.decodeFile(String path, Options opt)并不会真的返回一个Bitmap给你,它仅仅会把它的宽,高取回来给你,这样就不会占用太多的内存,也就不会那么频繁的发生OOM了。 ! G/ a1 C' ^9 V9 x& e8 F: l5 n+ K
示例代码如下:
  1. BitmapFactory.Options options = new BitmapFactory.Options();; D; b- {) R& ~" f% r2 D
  2. options.inJustDecodeBounds = true;) E3 r7 O% R. s$ f6 Q3 d' Y3 \. w
  3. Bitmap bmp = BitmapFactory.decodeFile(path, options);# u% G" P7 W7 F* f/ n) K' }; [9 g
  4. /* 这里返回的bmp是null */
复制代码 这段代码之后,options.outWidth 和 options.outHeight就是我们想要的宽和高了。 " M2 S' z& [/ L( }

有了宽,高的信息,我们怎样在图片不变形的情况下获取到图片指定大小的缩略图呢? 3 U7 W5 s) o! @, }0 W- Z7 K
比如我们需要在图片不变形的前提下得到宽度为200的缩略图。 . f+ I) D. ^; X
那么我们需要先计算一下缩放之后,图片的高度是多少 ; t5 G, A9 o% R# J- y5 I( P" k
  1. /* 计算得到图片的高度 */2 C' W8 @& M& L! a/ q; f6 D* K; y
  2. /* 这里需要主意,如果你需要更高的精度来保证图片不变形的话,需要自己进行一下数学运算 */
  3. int height = options.outHeight * 200 / options.outWidth;" C" t, A2 e# y4 ^* k
  4. , L& ~* R' @, z5 g9 T
  5. options.outWidth = 200;/ D5 U& s$ @+ {. Y! p3 A9 L
  6. options.outHeight = height;7 M# d+ t6 C& J. c8 r
  7. /* 这样才能真正的返回一个Bitmap给你 */
  8. options.inJustDecodeBounds = false;
  9. Bitmap bmp = BitmapFactory.decodeFile(path, options);
  10. image.setImageBitmap(bmp);
复制代码 这样虽然我们可以得到我们期望大小的ImageView
但是在执行BitmapFactory.decodeFile(path, options);时,并没有节约内存。 要想节约内存,还需要用到BitmapFactory.Options这个类里的inSampleSize这个成员变量。
我们可以根据图片实际的宽高和我们期望的宽高来计算得到这个值。 + s1 D& D, U3 B) d% F$ _
  1. inSampleSize = options.outWidth / 200;
复制代码 另外,为了节约内存我们还可以使用下面的几个字段:4 k, {( B; l( w/ B! B# U, {: O
  1. options.inPreferredConfig = Bitmap.Config.ARGB_4444; // 默认是Bitmap.Config.ARGB_8888- J3 M8 Q+ B- K. R3 g
  2. /* 下面两个字段需要组合使用 */8 ak8 k: ~+ s: S% I- K# y& T
  3. options.inPurgeable = true;
  4. options.inInputShareable = true;
复制代码

更多相关文章

  1. Android(安卓)Studio 快捷键整理分享
  2. Android使用GridView实现日历功能(详细代码)
  3. Android:WebView带划屏手势的浏览器实现
  4. android git 下载单个工程
  5. Android(安卓)Studio 快捷键(2)
  6. opencv在android预览上实现人脸识别(4)
  7. android轮播图示例
  8. Frame Animation 疑问,知道的请帮忙解答下,谢谢! Talking Tom
  9. Android上传多张图片的实例代码(RxJava异步分发)

随机推荐

  1. Android之ActivityManagerService浅谈
  2. android国际化(多语言)
  3. Android(安卓)代码混淆
  4. Android(安卓)Audio System 之二:AudioFli
  5. Android整机源码如何轻松下载?清华大学And
  6. Android(安卓)屏幕的旋转 onConfiguratio
  7. Android的消息机制
  8. Android(安卓)编程下 Touch 事件的分发和
  9. Android(安卓)中文 API (30) ―― Compound
  10. Android分享界面制作(底部滑出动画)