Bitmap

  android里的图像处理重要的类,支持jpg、png、bmp等格式的图像,BitmapDrawable是封装Bitmap的一个对象,
Bitmap实现在android.graphics包中。但是Bitmap类的构造函数是私有的,外面并不能实例化,只能是通过JNI(Java Native Interface JAVA本地调用)实例化。这必然是 某个辅助类提供了创建Bitmap的接口,而这个类的实现通过JNI接口来实例化Bitmap的,这个类就是BitmapFactory。利用BitmapFactory可以从一个指定文件中,利用decodeFile()解出Bitmap;也可以定义的图片资源中,利用decodeResource()解出Bitmap  

这样子可以用一张图片经过变化得到自己想要的,节省很多系统资源。

 由于手机系统资源有限,没用的图像要及时回收,否则会产生OOM,isRecycled()判读该Bitmap是否可回收,recycle()强制Bitmap自我回收。

1、android 系统图像的简单变化例子:



1                 // 获取图标图像的实例
 2                 Bitmap bitmap = BitmapFactory.decodeResource(this.getResources()
                    , R.drawable.ic_launcher);
 3                 // 绘制图像
 4                 canvas.drawBitmap(bitmap, 0, 0, paint);
 5                 // 保存当前状态
 6                 canvas.save();
 7 
 8                 // 绕图像中点旋转90度
 9                 canvas.rotate(30, bitmap.getWidth()/2, bitmap.getHeight()/2);
10                 // 为了不重叠,画在(50,0)这点,x,y轴相对旋转也发生变化
11                 canvas.drawBitmap(bitmap, 50, 0, paint);
12                 
13                 //恢复上次保存的状态与save()对应
14                 canvas.restore();
15                 canvas.drawBitmap(bitmap, 100, 100, paint);
16                 
17                 //平移
18                 canvas.translate(0, 50);
19                 canvas.drawBitmap(bitmap, 100, 100, paint);
20                 
21                 // 缩放,参数分别表示:x轴缩放2倍,y轴缩放2倍,3,4参数表示缩放的起始点
22                 canvas.scale(2, 2, 50+bitmap.getWidth()/2, 50+bitmap.getHeight()/2);
23                 canvas.drawBitmap(bitmap, 100, 100, paint);
24                 
25                 // 相对y轴镜像
26                 canvas.scale(1, -1, 50+bitmap.getWidth()/2, 50+bitmap.getHeight()/2);
27                 canvas.drawBitmap(bitmap, 100, 100, paint);



效果如下:

Android绘图bitmap android中bitmap_Android绘图bitmap

 

2、png格式和其他图像格式的区别是,png图像支持背景是透明的,
可以多个图像叠加在一起,而其他格式的图片就会被旁白覆盖



1                 //绘制一张背景图片,充满整个屏幕
 2                 Bitmap bitmap1 = BitmapFactory.decodeResource(this.getResources()
                    , R.drawable.background);
 3                 canvas.drawBitmap(bitmap1, 0, 0, paint);
 4                 
 5                 // png的图片,左边螃蟹边缘是透明的,因此不会有问题
 6                 Bitmap bitmap2 = BitmapFactory.decodeResource(this.getResources()
                    , R.drawable.crab);
 7                 canvas.drawBitmap(bitmap2, 20, 200, paint);
 8                 
 9                 // jpg的图片,右边螃蟹边缘把背景遮挡了
10                 Bitmap bitmap3 = BitmapFactory.decodeResource(this.getResources()
                    , R.drawable.carb2);
11                 canvas.drawBitmap(bitmap3, 200, 230, paint);



效果图如下:

Android绘图bitmap android中bitmap_Android绘图bitmap_02

左边的螃蟹图片是png格式的,右边则是jpg格式的,明显右边螃蟹还留有矩形的空白。

 

3、Bitmap通过均匀改变draw的横纵坐标或者切换图片就会呈现动画的效果,

Android绘图bitmap android中bitmap_人工智能_03

上图是一张波浪的图片

canvas.drawBitmap(bmp, x, y, new Paint());

新建个线程:x+=1,就可以看到海水在动。

Android绘图bitmap android中bitmap_移动开发_04

Android绘图bitmap android中bitmap_移动开发_05

Android绘图bitmap android中bitmap_fish_06

Android绘图bitmap android中bitmap_fish_07

Android绘图bitmap android中bitmap_java_08

Android绘图bitmap android中bitmap_Android绘图bitmap_09

Android绘图bitmap android中bitmap_人工智能_10

Android绘图bitmap android中bitmap_Android绘图bitmap_11

Android绘图bitmap android中bitmap_Android绘图bitmap_12

Android绘图bitmap android中bitmap_Android绘图bitmap_13

上面则是9张卡通鱼的图片,分别命名fish0~fish9,通过来回不断切换图片,就会看到鱼儿在游动

运行效果(由于博主不会录制gif图片,囧!就截2张图,读者自己脑补吧):

Android绘图bitmap android中bitmap_移动开发_14

Android绘图bitmap android中bitmap_人工智能_15


SurfaceView主要代码:


Android绘图bitmap android中bitmap_java_16

Android绘图bitmap android中bitmap_fish_17

1 public MySurfaceView(Context context) {
  2         super(context);
  3         // TODO Auto-generated constructor stub
  4         sfh = this.getHolder();
  5         sfh.addCallback(this);
  6         paint = new Paint();
  7         paint.setColor(Color.WHITE);
  8         paint.setAntiAlias(true);
  9         setFocusable(true);
 10         for (int i = 0; i < fishBmp.length; i++) {
 11             fishBmp[i] = BitmapFactory.decodeResource(this.getResources(), R.drawable.fish0 + i);
 12         }
 13     }
 14 
 15     @Override
 16     public void surfaceChanged(SurfaceHolder holder, int format, int width,
 17             int height) {
 18         // TODO Auto-generated method stub
 19         
 20     }
 21 
 22     @Override
 23     public void surfaceCreated(SurfaceHolder holder) {
 24         // TODO Auto-generated method stub
 25         bmp = BitmapFactory.decodeResource(this.getResources(), R.drawable.water);
 26         x = -bmp.getWidth() + this.getWidth();
 27         //Log.v("chendd", "bmp:"+bmp.getWidth() );
 28         //Log.v("chendd", "this:"+this.getWidth() );
 29         y = this.getHeight() - bmp.getHeight();
 30         flag = true;
 31         //实例线程
 32         th = new Thread(this);
 33         //启动线程
 34         th.start();
 35         //Mydraw();
 36     }
 37 
 38     private void Mydraw() {
 39         // TODO Auto-generated method stub
 40         try {
 41             canvas = sfh.lockCanvas();
 42             if (canvas != null) {
 43                 canvas.drawColor(Color.WHITE);
 44                 canvas.drawBitmap(bmp, x, y, new Paint());
 45                 canvas.drawBitmap(fishBmp[currentFrame], this.getWidth()/2, this.getHeight()-60, paint);
 46             }
 47         } catch (Exception e) {
 48             // TODO: handle exception
 49         } finally {
 50             if (canvas != null)
 51                 sfh.unlockCanvasAndPost(canvas);
 52         }
 53     }
 54 
 55     @Override
 56     public void surfaceDestroyed(SurfaceHolder holder) {
 57         // TODO Auto-generated method stub
 58         
 59     }
 60     
 61 
 62     @Override
 63     public boolean onTouchEvent(MotionEvent event) {
 64         // TODO Auto-generated method stub
 65         Mydraw();
 66         return true;
 67     }
 68 
 69     @Override
 70     public void run() {
 71         // TODO Auto-generated method stub
 72         while (flag) {
 73             long start = System.currentTimeMillis();
 74             Mydraw();
 75             logic();
 76             long end = System.currentTimeMillis();
 77             try {
 78                 if (end - start < 10) {
 79                     Thread.sleep(10 - (end - start));
 80                 }
 81             } catch (InterruptedException e) {
 82                 e.printStackTrace();
 83             }
 84         }
 85     }
 86 
 87     private void logic() {
 88         // TODO Auto-generated method stub
 89         //Log.v("chendd", "x:"+x );
 90         if(x == (-bmp.getWidth()/2 + this.getWidth())){
 91             x = -bmp.getWidth() + this.getWidth();
 92         }else {
 93             x+=1;
 94         }
 95         currentFrame++;
 96         if (currentFrame >= fishBmp.length) {
 97             currentFrame = 0;
 98         }
 99         
100     }

View Code