第十一天.Android图形技术

11.1 Paint类与Canvas类

11.1.1 绘图Paint类

Paint mPaint = new Paint();
/* 设置Paint为无锯齿 */
mPaint.setAntiAlias(true);
/* 设置Paint的颜色 */
mPaint.setColor(Color.RED);
mPaint.setColor(Color.BLUE);
/* 同样是设置颜色 */
mPaint.setColor(Color.rgb(255, 0, 0));
/* 提取颜色 */
Color.red(0xcccccc);
Color.green(0xcccccc);
/* 设置paint的颜色和Alpha值(a,r,g,b) */
mPaint.setARGB(255, 255, 0, 0);
/* 设置paint的Alpha值 */
mPaint.setAlpha(220);         


/* 设置字体的尺寸 */
mPaint.setTextSize(14);
// 设置paint的风格为“空心”.
// 当然也可以设置为“实心”(Paint.Style.FILL)
mPaint.setStyle(Paint.Style.STROKE);
// 设置“空心”的外框的宽度。
mPaint.setStrokeWidth(5);
/* 得到Paint的一些属性 */
Log.i(TAG, "paint的颜色:" + mPaint.getColor());
Log.i(TAG, "paint的Alpha:" + mPaint.getAlpha());
Log.i(TAG, "paint的外框的宽度:" +mPaint.getStrokeWidth());
Log.i(TAG, "paint的字体尺寸:" +mPaint.getTextSize());
/* 绘制一个矩形 */
canvas.drawRect((320 - 80) / 2, 20, (320- 80) / 2 + 80, 20 + 40, mPaint);
/* 设置风格为实心 */
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.GREEN);
/* 绘制绿色实心矩形 */
canvas.drawRect(0, 20, 40, 20 + 40,mPaint);

11.1.2 在线程中更新界面

public void run()  {
              while(!Thread.currentThread().isInterrupted())
              {
                     try{
                            Thread.sleep(100);
                     }
                     catch(InterruptedException e){
                            Thread.currentThread().interrupt();
                     }
                     //使用postInvalidate可以直接在线程中更新界面
                     postInvalidate();//会调用onDraw(Canvascanvas)方法
              }
       }

研究案例PaintDemo

11.1.3 Canvas画布类

public void onDraw(Canvas canvas){
              super.onDraw(canvas);              
              /*设置画布的颜色 */
              canvas.drawColor(Color.BLACK);           
              /*设置取消锯齿效果 */
              mPaint.setAntiAlias(true);         
              /*设置裁剪区域 */
              canvas.clipRect(10,10, 280, 260);             
              /*线锁定画布 */
              canvas.save();
              /*旋转画布 */
              canvas.rotate(45.0f);         
              /*设置颜色及绘制矩形 */
              mPaint.setColor(Color.RED);
              canvas.drawRect(newRect(15,15,140,70), mPaint);              
              /*解除画布的锁定 */
              canvas.restore();        
              /*设置颜色及绘制另一个矩形 */
              mPaint.setColor(Color.GREEN);
              canvas.drawRect(newRect(150,75,260,120), mPaint);
       }

研究案例PaintDemo2

11.2 SurfaceView类

11.2.1 SurfaceView类

  • 执行效率高
  • 可以直接访问画布Canvas
  • 开发手机游戏经常用

11.2.2 SurfaceView使用要点

  1. public class GameSurfaceView extendsSurfaceView implementsSurfaceHolder.Callback,Runnable
  2. 定义SurfaceHolder对象:
    SurfaceHoldermSurfaceHolder= this.getHolder();
    
  3. 添加回调:
    mSurfaceHolder.addCallback(this);
    this.setFocusable(true);
    
  4. 在回调方法surfaceCreated()中开启绘图线程。
  5. 在绘图线程中绘制图形。

11.2.3 SurfaceView回调方法

// 在surface的大小发生改变时激发
       publicvoid surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
       }
       //在surface创建时激发
       publicvoid surfaceCreated(SurfaceHolder holder){
              //开启绘图线程
              newThread(this).start();
       }
       //在surface销毁时激发
       publicvoid surfaceDestroyed(SurfaceHolder holder){
              //停止循环
              mbLoop= false;
       }

11.2.3 绘图线程

// 绘图循环
publicvoid run(){
              while(mbLoop){
                     try{
                            Thread.sleep(200);
                     }
                     catch(Exception e){

                     }
                     synchronized(mSurfaceHolder ){
                            draw();
                     }

              }
       }

11.2.4 绘图方法

public void draw() {
       //锁定画布,得到canvas
       Canvascanvas= mSurfaceHolder.lockCanvas();
       if(mSurfaceHolder==null || canvas == null ){
              return;
       }
       //绘图
       PaintmPaint = new Paint();
       mPaint.setColor(Color.BLACK);
       //绘制矩形--清屏作用
       canvas.drawRect(0,0, 320, 480, mPaint);
       mPaint.setColor(Color.BLUE);
       //绘制矩形
       canvas.drawCircle((320- 25) / 2, y, 50, mPaint);
       //绘制后解锁,绘制后必须解锁才能显示
       mSurfaceHolder.unlockCanvasAndPost(canvas);
}

研究完整案例GameSurfaceViewDemo

11.3 绘制几何形状

11.3.1 绘制几何形状

/* 定义矩形对象 */
       Rectrect1 = new Rect();
       /*设置矩形大小 */
       rect1.left= 5; rect1.top = 5; rect1.bottom = 25; rect1.right = 45;
       mPaint.setColor(Color.BLUE);
       /*绘制矩形 */
       canvas.drawRect(rect1,mPaint);                    
       /*绘制矩形 */
       canvas.drawRect(50,5, 90, 25, mPaint);

       /*绘制圆形(圆心x,圆心y,半径r,p) */
       canvas.drawCircle(40,70, 30, mPaint);

       /*定义椭圆对象 */
       RectFrectf1 = new RectF();
       /*设置椭圆大小 */
       rectf1.left= 80; rectf1.top = 30; rectf1.right = 120; rectf1.bottom = 70;
       /*绘制椭圆 */
       canvas.drawOval(rectf1,mPaint);

/* 绘制多边形 */
       Pathpath1 = new Path();                  
       /*设置多边形的点*/
       path1.moveTo(150+5,80-50);
       path1.lineTo(150+45,80-50);
       path1.lineTo(150+30,120-50);
       path1.lineTo(150+20,120-50);
       /*使这些点构成封闭的多边形 */
       path1.close();

       mPaint.setColor(Color.GRAY);
       /*绘制这个多边形 */
       canvas.drawPath(path1,mPaint);                   
       mPaint.setColor(Color.RED);
       mPaint.setStrokeWidth(3);
       /*绘制直线 */
       canvas.drawLine(5,110, 315, 110, mPaint);

研究完整案例PaintDemo3

11.3.2 ShapeDrawable绘制几何图形

/* 实例化ShapeDrawable对象并说明是绘制一个矩形 */
               ShapeDrawable mShapeDrawable = new ShapeDrawable(new RectShape());             
              //得到画笔paint对象并设置其颜色
              mShapeDrawable.getPaint().setColor(Color.RED); 
              Rectbounds = new Rect(5, 250, 55, 280);        
              /*设置图像显示的区域 */
              mShapeDrawable.setBounds(bounds);            
              mShapeDrawable.draw(canvas);/* 绘制图像 */

              /*实例化ShapeDrawable对象并说明是绘制一个椭圆 */
              mShapeDrawable= new ShapeDrawable(new OvalShape());       
              //得到画笔paint对象并设置其颜色
              mShapeDrawable.getPaint().setColor(Color.GREEN);          
              /*设置图像显示的区域 */
              mShapeDrawable.setBounds(70,250, 150, 280);            
              /*绘制图像 */
              mShapeDrawable.draw(canvas);       


Path path1 = new Path();
       /*设置多边形的点*/
       path1.moveTo(150+5,80+80-50);
       path1.lineTo(150+45,80+80-50);
       path1.lineTo(150+30,80+120-50);
       path1.lineTo(150+20,80+120-50);
       /*使这些点构成封闭的多边形 */
       path1.close();        
       //PathShape后面两个参数分别是宽度和高度
       mShapeDrawable= new ShapeDrawable(new PathShape(path1,150,150));
       //得到画笔paint对象并设置其颜色
       mShapeDrawable.getPaint().setColor(Color.BLUE);             
       /*设置图像显示的区域 */
       mShapeDrawable.setBounds(100,170, 200, 280);          
       /*绘制图像 */
       mShapeDrawable.draw(canvas);

研究案例PaintDemo3中GameView2.java

11.4 图形绘制与旋转缩放

11.4.1 绘制图像1

/*从资源文件中装载图片 */
       //getResources()->得到Resources
       //getDrawable()->得到资源中的Drawable对象,参数为资源索引ID
       //getBitmap()->得到Bitmap
        Bitmap mBitQQ = ((BitmapDrawable)getResources().getDrawable(R.drawable.qq)).getBitmap();

       /*清屏效果 */
       canvas.drawColor(Color.GRAY);
       /*在屏幕(0,0)处绘制图片mBitQQ */
       GameView.drawImage(canvas,mBitQQ, 0, 0);

drawImage()参考后面

11.4.2 绘制图像2

/**
 * @param            x屏幕上的x坐标      
 * @param          y屏幕上的y坐标
 * @param          w要绘制的图片的宽度    
 * @param          h要绘制的图片的高度
 * @param          bx图片上的x坐标
 * @param          by图片上的y坐标
 */
publicstatic void drawImage(Canvas canvas, Bitmap blt, int x, 
                            int y, int w, int h,int bx, int by)  {
              Rectsrc = new Rect();// 图片
              Rectdst = new Rect();// 屏幕           
              src.left= bx; src.top = by; src.right = bx + w;
              src.bottom= by + h;           
              dst.left= x; dst.top = y; dst.right = x + w;
              dst.bottom= y + h;
              canvas.drawBitmap(blt,src, dst, null);           
              src= null; dst = null;
       }

11.4.3 绘制图像3

      /**
        * 绘制一个Bitmap
        * @param canvas      画布
        * @param bitmap     图片
        * @param x        屏幕上的x坐标
        * @param y        屏幕上的y坐标
        */
public static void drawImage(Canvas canvas, Bitmap bitmap, int x, int y)
       {
              /*绘制图像 */
              canvas.drawBitmap(bitmap,x, y, null);
       }

还需要使用线程更新界面 研究案例PaintDemo5

11.4.5 图像旋转

public void onDraw(Canvas canvas){
              super.onDraw(canvas);
              MatrixmMatrix = new Matrix();             
              /*重置mMatrix */
              mMatrix.reset();          
              /*设置旋转 */
              mMatrix.setRotate(角度);

              /*按mMatrix得旋转构建新的Bitmap */
              BitmapmBitQQ2 = Bitmap.createBitmap(mBitQQ, 0, 0, BitQQwidth,BitQQheight, mMatrix,true);
              /*绘制旋转之后的图片 */
              GameView.drawImage(canvas,mBitQQ2, (320-BitQQwidth)/2, 10);   
              mBitQQ2= null;
       }

研究MatrixDemo

11.4.6 图像缩放

public void onDraw(Canvas canvas) {
              super.onDraw(canvas);

              /*重置mMatrix */
              mMatrix.reset();          
              /*设置缩放 */
              mMatrix.postScale(Scale,Scale);

              /*按mMatrix得旋转构建新的Bitmap */
              BitmapmBitQQ2 = Bitmap.createBitmap(mBitQQ, 0, 0, BitQQwidth,BitQQheight, mMatrix,true);
              /*绘制旋转之后的图片 */
              GameView.drawImage(canvas,mBitQQ2, (320-BitQQwidth)/2, 10);

              mBitQQ2= null;
       }

研究MatrixScaleDemo

11.5 用Shader类进行渲染

  • BitmapShader: Bitmap渲染
  • LinearGradient: 线性渐变渲染
  • ComposeShader: 混合渲染
  • RadialGradient: 环形渐变渲染
  • SweepGradient: 梯度渲染

研究案例ShaderDemo

示例下载