Bitmap是Android系统中的图像处理的最重要类之一。用它可以获取图像文件信息,进行图像剪切、旋转、缩放等操作,并可以指定格式保存图像文件。

一、Bitmap的生成

1.1 BitmapFactory decode出Bitmap

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


bitmap实现 java bitmap操作_位图


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

 

我们将详细介绍Android中的各种画图对象的使用,首先介绍我们最常用的Bitmap(位图)。位图是我们开 发中最常用的资源,毕竟一个漂亮的界面对用户是最有吸引力的。按照对位图的操作,分为以下几个功能分别介绍:

  1. 从资源中获取位图
  2. 获取位图的信息
  3. 显示位图
  4. 位图缩放
  5. 位图旋转

1. 从资源中获取位图

在前一篇幅介绍了:先获取Resource,然后可以通过资源ID获取Drawable,也可以通过资源ID获取资源文件的数据流。使用第一种方法 比较容易,下面详细说明第二种方法。通过Resource的函数:InputStream  openRawResource(int id)获取得到资源文件的数据流后,也可以通过2种方法来获取Bitmap,如下:

使用BitmapDrawable

(A Drawable that wraps a bitmap and can be tiled, stretched, or aligned.)

  1. 使用BitmapDrawable (InputStream is)构造一个BitmapDrawable;
  2. 使用BitmapDrawable类的getBitmap()获取得到位图;

BitmapDrawable也提供了显示位图等操作

使用BitmapFactory

(Creates Bitmap objects from various sources, including files, streams, and byte-arrays.)

  1. 使用BitmapFactory类decodeStream(InputStream is)解码位图资源,获取位图

BitmapFactory的所有函数都是static,这个辅助类可以通过资源ID、路径、文件、数据流等方式来获取位图。

以上方法在编程的时候可以自由选择,在Android SDK中说明可以支持的图片格式如下:png (preferred), jpg (acceptable), gif (discouraged),虽然bmp格式没有明确说明,但是在Android SDK Support Media Format中是明确说明了。

2. 获取位图的信息

要获取位图信息,比如位图大小、是否包含透明度、颜色格式等,获取得到Bitmap就迎刃而解了,这些信息在Bitmap的函数中可以轻松获取到。Android SDK中对Bitmap有详细说明,阅读起来也比较容易,不在此详细说明,这里只是辅助说明以下2点:

  • 在Bitmap中对RGB颜色格式使用Bitmap.Config定义,仅包括ALPHA_8、ARGB_4444、ARGB_8888、RGB_565,缺少了一些其他的,比如说RGB_555,在开发中可能需要注意这个小问题;
  • Bitmap还提供了compress()接口来压缩图片,不过AndroidSAK只支持PNG、JPG格式的压缩;其他格式的需要Android开发人员自己补充了。

3. 显示位图

显示位图需要使用核心类Canvas,可以直接通过Canvas类的drawBirmap()显示位图,或者借助于BitmapDrawable来 将Bitmap绘制到Canvas。具体如何显示位图不是主要的问题,主要问题是如何获取Canvas,参考Snake中的方法,做了个简单的例子 testView,提供给大家下载 。

testView例子介绍:其包含2个类testActivity,testView;testActivity继承与 Activity,testView继承与View。这个例子就是将testView直接作为testActivity的窗口,这样我们就可以直接在 testView画图了。具体如何实现的,请大家参考testActivity的onCreate()中的代码,以及layout/main.xml中的 设置。在testView的onDraw()直接画图,结果在例子程序运行后就可以直接在界面上显示了。

android Bitmap用法总结


1、Drawable → Bitmap



public static Bitmap drawableToBitmap(Drawable drawable) {
Bitmap bitmap = Bitmap
.createBitmap(
drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(),
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
// canvas.setBitmap(bitmap);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight());
drawable.draw(canvas);
return bitmap;
}



2、从资源中获取Bitmap


Resources res=getResources();
Bitmap bmp=BitmapFactory.decodeResource(res, R.drawable.pic);


3、Bitmap → byte[]

private byte[] Bitmap2Bytes(Bitmap bm){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
return baos.toByteArray();
}


4、byte[] → Bitmap

private Bitmap Bytes2Bimap(byte[] b){
if(b.length!=0){
return BitmapFactory.decodeByteArray(b, 0, b.length);
}
else {
return null;
}
}


5、保存bitmap

static boolean saveBitmap2file(Bitmap bmp,String filename){
CompressFormat format= Bitmap.CompressFormat.JPEG;
int quality = 100;
OutputStream stream = null;
try {
stream = new FileOutputStream("/sdcard/" + filename);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
e.printStackTrace();
}
return bmp.compress(format, quality, stream);
}

6、将图片按自己的要求缩放


// 图片源
Bitmap bm = BitmapFactory.decodeStream(getResources()
.openRawResource(R.drawable.dog));
// 获得图片的宽高
int width = bm.getWidth();
int height = bm.getHeight();
// 设置想要的大小
int newWidth = 320;
int newHeight = 480;
// 计算缩放比例
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// 取得想要缩放的matrix参数
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
// 得到新的图片
Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix,
true);
// 放在画布上
canvas.drawBitmap(newbm, 0, 0, paint);


7、bitmap的用法小结


BitmapFactory.Options option = new BitmapFactory.Options();
option.inSampleSize = 2; //将图片设为原来宽高的1/2,防止内存溢出
Bitmap bm = BitmapFactory.decodeFile("",option);//文件流
URL url = new URL("");
InputStream is = url.openStream();
Bitmap bm = BitmapFactory.decodeStream(is);

android:scaleType:

android:scaleType是控制图片如何resized/moved来匹对ImageView的size。ImageView.ScaleType /

android:scaleType值的意义区别:

CENTER /center 按图片的原来size居中显示,当图片长/宽超过View的长/宽,则截取图片的居中部分

显示

CENTER_CROP / centerCrop 按比例扩大图片的size居中显示,使得图片长(宽)等于或大于View的长

(宽)

CENTER_INSIDE / centerInside 将图片的内容完整居中显示,通过按比例缩小或原来的size使得图片

长/宽等于或小于View的长/宽

Generated by Foxit PDF Creator © Foxit Software

http://www.foxitsoftware.com For evaluation only.

FIT_CENTER / fitCenter 把图片按比例扩大/缩小到View的宽度,居中显示

FIT_END / fitEnd 把图片按比例扩大/缩小到View的宽度,显示在View的下部分位置

FIT_START / fitStart 把图片按比例扩大/缩小到View的宽度,显示在View的上部分位置

FIT_XY / fitXY 把图片 不按比例 扩大/缩小到View的大小显示

MATRIX / matrix 用矩阵来绘制,动态缩小放大图片来显示。

//放大缩小图片

public static Bitmap zoomBitmap(Bitmap bitmap,int w,int h){
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Matrix matrix = new Matrix();
float scaleWidht = ((float)w / width);
float scaleHeight = ((float)h / height);
matrix.postScale(scaleWidht, scaleHeight);
Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix,
true);
return newbmp;
}


//将Drawable转化为Bitmap


public static Bitmap drawableToBitmap(Drawable drawable){
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height,
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0,0,width,height);
drawable.draw(canvas);
return bitmap;
}


//获得圆角图片的方法

public static Bitmap getRoundedCornerBitmap(Bitmap bitmap,float roundPx){
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}

//获得带倒影的图片方法


public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap){
final int reflectionGap = 4;
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Matrix matrix = new Matrix();
matrix.preScale(1, -1);
Bitmap reflectionImage = Bitmap.createBitmap(bitmap,
0, height/2, width, height/2, matrix, false);
Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height/2),
Config.ARGB_8888);
Canvas canvas = new Canvas(bitmapWithReflection);
canvas.drawBitmap(bitmap, 0, 0, null);
Paint deafalutPaint = new Paint();
canvas.drawRect(0, height,width,height + reflectionGap,
deafalutPaint);
canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
Paint paint = new Paint();
LinearGradient shader = new LinearGradient(0,
bitmap.getHeight(), 0, bitmapWithReflection.getHeight()
+ reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
paint.setShader(shader);
// Set the Transfer mode to be porter duff and destination in
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
// Draw a rectangle using the paint with our linear gradient
canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
+ reflectionGap, paint);
return bitmapWithReflection;
}
}