Android图形处理之Bitmap

Bitmap是Android系统中的图像处理的最重要类之一。用它能够获取图像文件信息,进行图像剪切、旋转、缩放等操做,并能够指定格式保存图像文件。本文从应用的角度,着重介绍怎么用Bitmap来实现这些功能。html

 

1、Bitmap的生成android

1.1 BitmapFactory decode出Bitmap数组

    Bitmap实如今android.graphics包中。可是Bitmap类的构造函数是私有的,外面并不能实例化,只能是经过JNI实例化。这必然是 某个辅助类提供了建立Bitmap的接口,而这个类的实现经过JNI接口来实例化Bitmap的,这个类就是BitmapFactory。函数

Android图像处理之Bitmap类

图1、BitmapFactory主要方法及Options选项编码

 

利用BitmapFactory能够从一个指定文件中,利用decodeFile()解出Bitmap;也能够定义的图片资源中,利用decodeResource()解出Bitmap。spa

 

1.2 decode时的选项code

在使用方法decodeFile()/decodeResource()时,均可以指定一个BitmapFacotry.Optionsorm

利用Options的下列属性,能够指定decode的选项:xml

  • inPreferredConfig 指定decode到内存中,手机中所采用的编码,可选值定义在Bitmap.Config中。缺省值是ARGB_8888。htm

  • inJustDecodeBounds 若是设置为true,并不会把图像的数据彻底解码,亦即decodeXyz()返回值为null,可是Options的outAbc中解出了图像的基本信息。

  • inSampleSize 设置decode时的缩放比例。

 

利用Options的这些值就能够高效的获得一幅缩略图。

Android图像处理之Bitmap类

图2、BitmapFactory.decodeFile()

 

先设置inJustDecodeBounds= true,调用decodeFile()获得图像的基本信息[Step#2~4];

利用图像的宽度(或者高度,或综合)以及目标的宽度,获得inSampleSize值,再设置inJustDecodeBounds= false,调用decodeFile()获得完整的图像数据[Step#5~8]。

先获取比例,再读入数据,若是欲读入大比例缩小的图,将显著的节约内容资源。有时候还会读入大量的缩略图,这效果就更明显了。

 

2、利用Bitmap和Matrix实现图像变换

    Bitmap能够和Matrix结合实现图像的剪切、旋转、缩放等操做。

Android图像处理之Bitmap类

图3、Bitmap方法

 

用源Bitmap经过变换生成新的Bitmap的方法:

?

1
2
3
4
5
public     static     Bitmap createBitmap(Bitmap source,     int     x,     int     y, intwidth,     int     height, 
                 Matrix m,     boolean     filter) 
public     static     Bitmap createBitmap(Bitmap source,     int     x,     int     y, intwidth,     int     height) 
public     static     Bitmap createScaledBitmap(Bitmap src,     int     dstWidth, 
                 int     dstHeight,     boolean     filter)

第一个方法是最终的实现,后两种只是对第一种方法的封装。

第二个方法能够从源Bitmap中指定区域(x,y, width, height)中挖出一块来实现剪切;第三个方法能够把源Bitmap缩放为dstWidth x dstHeight的Bitmap。

 

设置Matrix的Rotate(经过setRotate())或者Scale(经过setScale()),传入第一个方法,可实现旋转或缩放。

Android图像处理之Bitmap类

图4、Bitmap实现旋转

 

3、保存图像文件

    通过图像变换以后的Bitmap里的数据能够保存到图像压缩文件里(JPG/PNG)。

Android图像处理之Bitmap类

图5、保存Bitmap数据到文件

 

这个操做过程当中,Bitmap.compress()方法的参数format可设置JPEG或PNG格式;quality可选择压缩质量;fOut是输出流(OutputStream),这里的FileOutputStream是OutputStream的一个子类。

 

总结一下,本文介绍Bitmap的使用方法——用Bitmap实现图像文件的读取和写入,并用Bitmap实现图像的剪切、旋转和缩放变换。


下面主要介绍加载位图的5中方式:

   1 .【加载位图】经过文件路径加载位图,显示原图,大小比例不变            

          Bitmap bmp=BitmapFactory.decodeFile("/mnt/sdcard/dog.jpg");            

         imageView.setImageBitmap(bmp);     

    2.【加载位图】经过文件路径加载位图,(若scale 值为n>1) 则图片长,宽变为原来的1/n,至关于把图片压缩到原来的1/(n*n),加载到手机内存占用的空间小,咱们能够再xml文件中设置ImageView的scaleType=fitCenter属性, 进行拉伸自适应操做,拉伸后的图像不是很清楚,但仍是能够接受的。     

        Options options=new Options();      

        options.inSampleSize=2;     

        Bitmap bm=BitmapFactory.decodeFile("/mnt/sdcard/dog.jpg", options);  

        imageView.setImageBitmap(bm);      

    

 3.【加载位图】经过文件路径加载位图,此种方式,能够把原图缩小,或放大。下面例子是先压缩再放大。        

         Options opts=new Options();          //设置仅加载位图边界信息(至关于位图的信息,但没有加载位图)          

         opts.inJustDecodeBounds=true;          //加载指定路径图片的边界信息,保存到opts中         

         BitmapFactory.decodeFile("/mnt/sdcard/dog.jpg", opts);          //计算收缩比例          

        int xScale=opts.outWidth/200;        

        int yScale=opts.outHeight/200;        

        opts.inSampleSize=xScale>yScale?xScale:yScale;          //设置加载边界信息为false     

         opts.inJustDecodeBounds=false

         Bitmap bm=BitmapFactory.decodeFile("/mnt/sdcard/dog.jpg", opts); 

         imageView.setImageBitmap(bm);           


4.【加载位图】经过输入流加载位图           

        FileInputStream is;          

            try {             

                     is = new FileInputStream("/mnt/sdcard/dog.jpg");        

                      Bitmap bm=BitmapFactory.decodeStream(is);            

                      imageView.setImageBitmap(bm);                    

                    } catch (FileNotFoundException e) {    

                       e.printStackTrace();          

                    }                       


 5.【加载位图】经过字节数组加载位图,图片长,宽减半;          

            ByteArrayOutputStream out;          

                    try {              

                            FileInputStream fis=new FileInputStream("/mnt/sdcard/dog.jpg");              

                            BufferedInputStream bis=new BufferedInputStream(fis);             

                            out = new ByteArrayOutputStream();    

                             int hasRead=0;             

                             byte[] buffer=new byte[1024*2];              

                             while((hasRead=bis.read(buffer))>0){        

                                        //读出多少数据,向输出流中写入多少     

                                         out.write(buffer);                

                                          out.flush();             

                                 }             

                                  out.close();              

                                    fis.close();           

                                     bis.close();             

                                      byte[] data=out.toByteArray();            

                                          //长宽减半            

                                         Options opts=new Options();  

                                          opts.inSampleSize=2;       

                                           Bitmap bm=BitmapFactory.decodeByteArray(data, 0, data.length, opts);             

                                             imageView.setImageBitmap(bm);   

                     } catch (FileNotFoundException e) {      

                                // TODO Auto-generated catch block            

                                  e.printStackTrace();         

                             } catch (IOException e) {              

                                // TODO Auto-generated catch block            

                                     e.printStackTrace();          }    }  }  

相关文章
相关标签/搜索