Android图形处理之Bitmap

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

一、Bitmap的生成

1.1 BitmapFactory decode出Bitmap

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


图一、BitmapFactory主要方法及Options选项

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

1.2 decode时的选项

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

利用Options的下列属性,可以指定decode的选项:

  • inPreferredConfig 指定decode到内存中,手机中所采用的编码,可选值定义在Bitmap.Config中。缺省值是ARGB_8888。
  • inJustDecodeBounds 如果设置为true,并不会把图像的数据完全解码,亦即decodeXyz()返回值为null,但是Options的outAbc中解出了图像的基本信息。
  • inSampleSize 设置decode时的缩放比例。

利用Options的这些值就可以高效的得到一幅缩略图。


图二、BitmapFactory.decodeFile()

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

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

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

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

Bitmap可以和Matrix结合实现图像的剪切、旋转、缩放等操作。


图三、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()),传入第一个方法,可实现旋转或缩放。


图四、Bitmap实现旋转

三、保存图像文件

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

图五、保存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();          }    }  }

时间: 2024-07-30 01:11:59

Android图形处理之Bitmap的相关文章

四十六、android中的Bitmap

四十六.android中的Bitmap: http://www.cnblogs.com/linjiqin/archive/2011/12/28/2304940.html 四十七.实现调用Android手机的拍照功能: http://www.cnblogs.com/linjiqin/archive/2011/12/28/2304970.html

Android客户端中Bitmap的下载过程和缓存机制

加载流程: if(内存命中){ 从内存中读取 }else{ create AsyncTasks,task中的多个Runnable是通过堆栈先进后出的方式来调度,而非队列式的先进先出,目的是最先加载用户最近划到或打开的图片. } AsyncTask: //do in background——该后台进程在用户scroll列表的时候会暂停,从而减小了列表划动时cpu的overhead,此方法也被ImageLoader和facebook的官方app所使用. if(磁盘缓存命中){ 从缓存中读取 }els

Android -- Drawable与Bitmap

Drawable                                                                                 以下这个是测试加载1000个Drawable对象的代码: public class Main extends Activity { int number = 1000; Drawable[] array; @Override public void onCreate(Bundle savedInstanceState)

Android技术6:Android中对于Bitmap的处理

很多Android应用在运行时,会遇到运行缓慢,不流畅等影响用户体验问题,这有一部分原因与图片有密切关系.当android应用需要加载较大较多的照片时,经常反应迟缓,甚至由于OOM,造成系统奔溃.下面将提供一种可行的解决方案. 1.获取图片的宽高属性 1 BitmapFactory.Options options=new BitmapFactory.Options(); 2 options.inJustDecodeBounds=true; 3 BitmapFactory.decodeFile(f

【转】Android开发之Bitmap的内存优化详解

本文来源:转载自: http://mobile.51cto.com/abased-410796.htm 在Android应用里,最耗费内存的就是图片资源.而且在Android系统中,读取位图Bitmap时,分给虚拟机中的图片的堆栈大小只有8M,如果超出了,就会出现OutOfMemory异常.所以,对于图片的内存优化,是Android应用开发中比较重要的内容. 1.要及时回收Bitmap的内存 Bitmap类有一个方法recycle(),从方法名可以看出意思是回收.这里就有疑问了,Android系

Android图像处理之Bitmap类

Bitmap是Android系统中的图像处理的最重要类之一.用它可以获取图像文件信息,进行图像剪切.旋转.缩放等操作,并可以指定格式保存图像文件.本文从应用的角度,着重介绍怎么用Bitmap来实现这些功能. 一.Bitmap的生成 1.1 BitmapFactory decode出Bitmap Bitmap实现在android.graphics包中.但是Bitmap类的构造函数是私有的,外面并不能实例化,只能是通过JNI实例化.这必然是 某个辅助类提供了创建Bitmap的接口,而这个类的实现通过

Android中实现Bitmap在自定义View中的放大与拖动

一:基本实现思路 基于View类实现自定义View –MyImageView类.在使用View的Activity类中完成OnTouchListener接口,实现对自定义View的触摸事件监听 放大与拖动 基于单点触控实现Bitmap对象在View上的拖动.并且检测View的边缘,防止拖动过界.基于两个点触控实现Bitmap对象在View上的放大.并且检测放大倍数.基于Matrix对象实现对Bitmap在View上放大与平移变换 Bitmap对象在View中的更新与显示 通过重载onDraw方法,

android:GLSurfaceView绘制bitmap图片及glViewport调整的效果

首先看一下GLSurfaceView是怎样绘制的.正如android开发文档中描写叙述的那样,我们须要new一个GLSurfaceView对象,然后设置一个实现了Renderer接口的对象,我们须要写一个MyRender类,实现Renderer的方法等等.我们先看一下Activity的写法.它不须要一个布局文件,我们将GLSurfaceView对象作为activity的contentview就可以.例如以下: package net.mobctrl.glsurfaceviewbmp; impor

Android 设置图片 Bitmap任意透明度

两种思路,第一种思路是通过对Bitmap进行操作,将Bitmap的像素值get到一个int[]数组里,因为在android里Bitmap通常是ARGB8888格式,所以最高位就是A通道的值,对齐进行改变后再新建一个Bitmap即可.第二种思路是通过设置canvas的paint的透明度,然后通过canvas.drawBitmap()来改变View的透明度.具体代码如下: 第一种思路: public static Bitmap getTransparentBitmap(Bitmap sourceIm