安卓开发之Bitmap(一)

Bitmap是安卓开发中和图片相关的最常见的一个类。无论是图片的处理,加载,以及自定义控件,都和Bitmap息息相关。
Bitmap的使用并不是很困难,但是在使用过程中及其容易导致OOM,这也是让开发者最烦心的事之一。合理有效的使用Bitmap,避免OOM,很有必要。

1,通过BitmapFactory创建Bitmap

通过这种方式创建Bitmap,大概有四种小的方式:

  • 通过资源文件进行创建,比较常见
  • 通过数组进行创建,这里的数组指的是字节数组
  • 通过I/O流进行创建
  • 通过文件路径进行创建
    这四种方式涉及到的方法比较多,在这里我们讲一些比较典型的方法。

decodeResource(Resources res, int id)

直接通过资源文件进行创建,第一个参数是Resources ,如果是在Activity中使用,直接getResources()就可以得到该参数。第二个参数是资源Id。
例如:

bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.picture);

decodeResource(Resources res, int id, Options opts)

和上面的方法相比,多了一个Options 参数。这个参数非常重要,可以根据所需要的尺寸高效加载图片,是防止OOM的有效解决办法。后面会专门讨论OOM。


        BitmapFactory.Options options=new BitmapFactory.Options();
        /**
        ...在这里对options参数进行设定
        */
        bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.eight,options);

decodeByteArray(byte[] data, int offset,int length)

从指定字节数组的offset位置开始,将长度为length的字节数据解析成Bitmap对象。offset是偏移量,一般设置为0。length一般为数组长度。其中字节数组包含所有的图片信息。decodeByteArray(byte[] data, int offset, int length, Options opts)只是多了一个Options 参数,不多解释。

decodeFile(String pathName)

根据图片的文件路径生成Bitmap。同理,decodeFile(String pathName, Options opts)也是如此。
例如拍照程序中:

   File file=new File(Environment.getExternalStorageDirectory(),"拼图");
        if(!file.exists()){
            file.mkdir();
        }
        File output=new File(file,System.currentTimeMillis()+".jpg");
        String imagePath=output.getPath();
 Bitmap bitmap= BitmapFactory.decodeFile(imagePath);

decodeStream(InputStream is)

通过I/O流进行加载,比较常见于从网络上获取图片。

        myUrl=new URL(url);
HttpURLConnection conn=(HttpURLConnection)myUrl.openConnection();
conn.setConnectTimeout(5000);
conn.connect();
InputStream is=conn.getInputStream();
bitmap= BitmapFactory.decodeStream(is);

decodeStream(InputStream is, Rect outPadding, Options opts)

和上一个方法相比,多了两个参数。最后一个参数不必多数,主要在于第二个参数。
对于第二个参数,API是这么解释的:
If not null, return the padding rect for the bitmap if it exists,otherwise set padding to [-1,-1,-1,-1]. If no bitmap is returned (null) then padding is unchanged.
翻译过来大概是:如果此参数不为空,那么返回该Rect作为Bitmap的边距。否则,将边距设置为[-1,-1,-1,-1。如果返回的Bitmap为空,那么边距的值不会改变。
其中decodeStream(InputStream is)的实现就是调用了该方法,只不过后两个参数都设置为null。

Bitmap decodeFileDescriptor(FileDescriptor fd)

通过文件描述符创建Bitmap,我没有使用过该方法,了解的不多。本质上似乎还是利用了I/O流。
decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts)解释同上。

2,通过Bitmap的静态工厂方法创建Bitmap

createBitmap(Bitmap source, int x, int y, int width, int height)

截取指定宽高的图片。 int x, int y是截取的起始坐标。需要注意的是,起始坐标X(Y)+width(height)必须小于原图的宽(高),否则会抛出IllegalArgumentException异常。
例:

Bitmap blackBitmap=Bitmap.createBitmap(blackBitmap,0,0,itemWidth,itemHeight);

createBitmap(Bitmap source, int x,int y,int width,int height ,Matrix m,boolean fliter)

和上面的方法基本一致,Matrix 是一个变换矩阵,通过这个矩阵可以设置图片的变换规则。最后一个参数表示是否添加过滤,如果为true表示添加。只有当矩阵包含多个变换时,才会作用。

createBitmap (int width, int height, Bitmap.Config config)

返回一个指定高度和宽度的可改变的位图。它的初始密度由getDensity()决定。最后一个参数config指明bitmap的质量,具体是指图片的每一个像素有多少个二进制位组成,常见的取值有:Bitmap.Config ARGB_8888 ,Bitmap.Config ARGB_4444,Bitmap.Config RGB_565,Bitmap.Config ALPHA_8。每个像素占用的像素越多,图像显示越逼真,但付出的代价是占用的内存会更多。

createBitmap(DisplayMetrics display, int width,int height, Config config)

第一个参数指明图片的初始密度。DisplayMetrics 类提供了一种关于显示的通用信息,如显示大小,分辨率和字体。

createBitmap(DisplayMetrics display, int colors[],int width, int height, Config config)

根据传入的宽高参数返回一个不可变的Bitmap,每一个像素的取值都来源于颜色数组。Bitmap的初始密度由DisplayMetrics 指定。最后一个参数用来指定图片显示的质量。
颜色数组的长度至少为width*height,否则报异常。

createBitmap(int colors[], int offset, int stride,int width, int height, Config config)

主要是第二个参数和第三个参数,其他几个参数前面都讲了。这两个参数都是针对colors数组的。offset值的是偏移量,就是从第几个元素开始。stride不太好理解,源码的注释是这样写的:Number of colors in the array between rows (must be >=width or <= -width)。colors[]中的行间距个数值(必须大于等于位图宽度)。不能为负数。

你可能感兴趣的:(android)