android BitmapFactory.Options(总结网络中出现的一些)

来源:互联网 发布:南京淘宝美工培训班 编辑:程序博客网 时间:2024/05/22 00:08

public Bitmap

inBitmap

If set, decode methods that take the Options objectwill 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 todither the decoded image.

public boolean

inInputShareable

This field works in conjuction withinPurgeable.

public boolean

inJustDecodeBounds

If set to true, the decoder will return null (nobitmap), but the out…

public boolean

inMutable

If set, decode methods will always return a mutableBitmap instead of an immutable one.

public boolean

inPreferQualityOverSpeed

If inPreferQualityOverSpeed is set to true, thedecoder will try to decode the reconstructed image to a higherquality even at the expense of the decoding speed.

publicBitmap.Config

inPreferredConfig

If this is non-null, the decoder will try to decodeinto this internal configuration.

public boolean

inPurgeable

If this is set to true, then the resulting bitmapwill allocate its pixels such that they can be purged if the systemneeds to reclaim memory.

public int

inSampleSize

If set to a value > 1, requests the decoder tosubsample the original image, returning a smaller image to savememory.

public boolean

inScaled

When this flag is set,if inDensity and inTargetDensity arenot 0, the bitmap will be scaled tomatch inTargetDensity whenloaded, rather than relying on the graphics system scaling it eachtime it is drawn to a Canvas.

public int

inScreenDensity

The pixel density of the actual screen that isbeing used.

public int

inTargetDensity

The pixel density of the destination this bitmapwill be drawn to.

public byte[]

inTempStorage

Temp storage to use for decoding.

public boolean

mCancel

Flag to indicate that cancel has been called onthis object.

public int

outHeight

The resulting height of the bitmap, set independentof the state of inJustDecodeBounds.

public String

outMimeType

If known, this string is set to the mimetype of thedecoded image.

public int

outWidth

The resulting width of the bitmap, set independentof the state of inJustDecodeBounds.

这个表格是从android sdk文档里摘出来的,简单看一下说明就明白是什么意思了。
下面我们回到我们的主题上来:怎样获取图片的大小?
思路很简单:
首先我们把这个图片转成Bitmap,然后再利用Bitmap的getWidth()和getHeight()方法就可以取到图片的宽高了。
新问题又来了,在通过BitmapFactory.decodeFile(Stringpath)方法将突破转成Bitmap时,遇到大一些的图片,我们经常会遇到OOM(Out OfMemory)的问题。怎么避免它呢?
这就用到了我们上面提到的BitmapFactory.Options这个类。

BitmapFactory.Options这个类,有一个字段叫做 inJustDecodeBounds 。SDK中对这个成员的说明是这样的:
If set to true, the decoderwill return null (no bitmap), but theout…
也就是说,如果我们把它设为true,那么BitmapFactory.decodeFile(Stringpath, Optionsopt)并不会真的返回一个Bitmap给你,它仅仅会把它的宽,高取回来给你,这样就不会占用太多的内存,也就不会那么频繁的发生OOM了。
示例代码如下:

  1. BitmapFactory.Options options = newBitmapFactory.Options();
  2. options.inJustDecodeBounds = true;
  3. Bitmap bmp = BitmapFactory.decodeFile(path, options);

复制代码

这段代码之后,options.outWidth 和 options.outHeight就是我们想要的宽和高了。

有了宽,高的信息,我们怎样在图片不变形的情况下获取到图片指定大小的缩略图呢?
比如我们需要在图片不变形的前提下得到宽度为200的缩略图。
那么我们需要先计算一下缩放之后,图片的高度是多少 

  1. int height = options.outHeight * 200 / options.outWidth;
  2. options.outWidth = 200;
  3. options.outHeight = height; 
  4. options.inJustDecodeBounds = false;
  5. Bitmap bmp = BitmapFactory.decodeFile(path, options);
  6. image.setImageBitmap(bmp);

复制代码

这样虽然我们可以得到我们期望大小的ImageView
但是在执行BitmapFactory.decodeFile(path,options);时,并没有节约内存。
要想节约内存,还需要用到BitmapFactory.Options这个类里的 inSampleSize 这个成员变量。
我们可以根据图片实际的宽高和我们期望的宽高来计算得到这个值。

  1. inSampleSize = options.outWidth / 200;

另外,为了节约内存我们还可以使用下面的几个字段:

  1. options.inPreferredConfig =Bitmap.Config.ARGB_4444;    //默认是Bitmap.Config.ARGB_8888
  2. options.inPurgeable = true;
  3. options.inInputShareable = true;


加载和显示图片是很消耗内存的一件事,BitmapFactory.Options 类,  允许我们定义图片以何种方式如何读到内存,

    BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();      bmpFactoryOptions.inSampleSize = 8;      Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);      imv.setImageBitmap(bmp);  
上面的代码使图片变成原来的1/8.
    //imv = (ImageView) findViewById(R.id.ReturnedImageView);              Display currentDisplay = getWindowManager().getDefaultDisplay();              int dw = currentDisplay.getWidth();              int dh = currentDisplay.getHeight();                try             {              BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();              bmpFactoryOptions.inJustDecodeBounds = true;              Bitmap bmp = BitmapFactory.decodeStream(getContentResolver().                      openInputStream(imageFileUri), null,  bmpFactoryOptions);                    int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)dh);              int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)dw);                    Log.v("HEIGHRATIO", ""+heightRatio);              Log.v("WIDTHRATIO", ""+widthRatio);                    if (heightRatio > 1 && widthRatio > 1)              {                  bmpFactoryOptions.inSampleSize =  heightRatio > widthRatio ? heightRatio:widthRatio;              }              bmpFactoryOptions.inJustDecodeBounds = false;              bmp = BitmapFactory.decodeStream(getContentResolver().                      openInputStream(imageFileUri), null,  bmpFactoryOptions);                 returnedImageView.setImageBitmap(bmp);             }             catch (FileNotFoundException e)             {                 Log.v("ERROR", e.toString());                   }  
上面的代码让图片根据窗口大小改变

bmpFactoryOptions.inJustDecodeBounds = true这一行让代码只解码图片的Bounds

如果设置为真,译码器将返回null(没有图),但是……领域仍将被设置,允许调用者来查询图而无需为其像素分配内存。

1.inSampleSize(设置缩放为原来的四分之一)
BitmapFactory.Options opts = new BitmapFactory.Options();opts.inSampleSize = 4;Bitmap bitmap = BitmapFactory.decodeFile(imageFile, opts);
2.inJustDecodeBounds
BitmapFactory.Options opts = new BitmapFactory.Options();opts.inJustDecodeBounds = true;Bitmap bitmap = BitmapFactory.decodeFile(imageFile, opts);
设置inJustDecodeBounds为true后,decodeFile并不分配空间,但可计算出原始图片的长度和宽度,即opts.width和opts.height。有了这两个参数,再通过一定的算法,即可得到一个恰当的inSampleSize。
综合上述(1,2),完整代码是
    public static Bitmap createImageThumbnail(String filePath){           Bitmap bitmap = null;           BitmapFactory.Options opts = new BitmapFactory.Options();           opts.inJustDecodeBounds = true;           BitmapFactory.decodeFile(filePath, opts);                 opts.inSampleSize = computeSampleSize(opts, -1, 128*128);           opts.inJustDecodeBounds = false;                 try {               bitmap = BitmapFactory.decodeFile(filePath, opts);           }catch (Exception e) {              // TODO: handle exception          }          return bitmap;      }            public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {          int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);          int roundedSize;          if (initialSize <= 8) {              roundedSize = 1;              while (roundedSize < initialSize) {                  roundedSize <<= 1;              }          } else {              roundedSize = (initialSize + 7) / 8 * 8;          }          return roundedSize;      }            private static int computeInitialSampleSize(BitmapFactory.Options options,int minSideLength, int maxNumOfPixels) {          double w = options.outWidth;          double h = options.outHeight;          int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));          int upperBound = (minSideLength == -1) ? 128 :(int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));          if (upperBound < lowerBound) {              // return the larger one when there is no overlapping zone.              return lowerBound;          }          if ((maxNumOfPixels == -1) && (minSideLength == -1)) {              return 1;          } else if (minSideLength == -1) {              return lowerBound;          } else {              return upperBound;          }      }  




原创粉丝点击