Canvas

Canvas 的主要结构是一个位图矩阵(从起构造参数须要一个位图Bitmap就可推断), 当进行 save 、savelayerXX的时候,会建立一个新的位图矩阵(大小和原来同样,可是不包含原来矩阵的内容,即没有渲染),调用restore、restoreXX的时候,会把当前操做的矩阵内容合并到其下层的矩阵,并把当前矩阵丢弃(弹出),并把其下层的矩阵设置当前矩阵。java

伴随每个位图矩阵,还有一个变换矩阵(可经过canvas.getMatrix 获得),当进行 translate、rotate、scale等操做时,改变的是变换矩阵,每次进行渲染时(drawXX),都会使用变换矩阵, 因此translate、rotate、scale等变换操做要在drawXX以前调用, 不然不起做用。canvas


一个画图须要四大基本要素:ide

一、一个用来保存像素的Bitmap;动画

二、一个Canvas画布,绘制Bitmap操做;this

三、绘制的东西spa

四、绘制的画笔Paint(颜色和样式).net

一、如何得到一个Canvas对象。

Canvas对象的获取方式有三种:rest

第一种咱们经过重写View.onDraw方法,View中的Canvas对象会被当作参数传递过来,咱们操做这个Canvas,效果会直接反应在View中。code

第二种就是当你想本身建立一个Canvas对象。从上面的基本要素能够明白,一个Canvas对象必定是结合了一个Bitmap对象的。因此必定要为一个Canvas对象设置一个Bitmap对象。orm

        //获得一个Bitmap对象,固然也可使用别的方式获得。可是要注意,改bitmap必定要是mutable(异变的)  
        Bitmap b = Bitmap.createBitmap(100,100, Bitmap.Config.ARGB_8888);  
        Canvas c = new Canvas(b);  
        /*先new一个Canvas对象,在调用setBitmap方法,同样的效果 
         * Canvas c = new Canvas(); 
         * c.setBitmap(b); 
         */

第三种方式,是调用SurfaceHolder.lockCanvas(),返回一个Canvas对象。

二、canvas能够绘制的内容

  1)填充

      drawARGB(int a, int r, int g, int b)
      drawColor(int color)
      drawRGB(int r, int g, int b)
      drawColor(int color, PorterDuff.Mode mode)

  

2)几何图形

     canvas.drawArc (扇形)
     canvas.drawCircle(圆)
     canvas.drawOval(椭圆)
     canvas.drawLine(线)
     canvas.drawPoint(点)
     canvas.drawRect(矩形)
     canvas.drawRoundRect(圆角矩形)
     canvas.drawVertices(顶点)
     cnavas.drawPath(路径)

   

3)图片

    canvas.drawBitmap (位图)
    canvas.drawPicture (图片)

   

4)文本

canvas.drawText


3. Canvas的保存和回滚

为了方便一些转换操做,Canvas还提供了保存和回滚属性的方法(save和restore),好比你能够先保存目前画纸的位置(save),而后旋转90度,向下移动100像素后画一些图形,画完后调用restore方法返回到刚才保存的位置。

Canvas提供的该功能的API以下:

/** 
     * 保存当前的matrix和clip到私有的栈中(Skia内部实现)。任何matrix变换和clip操做都会在调用restore的时候还原。 
     * @return 返回值能够传入到restoreToCount()方法,以返回到某个save状态以前。 
     */  
    public native int save();  
  
    /** 
     * 传入一个标志,来表示当restore 的时候,哪些参数须要还原。该参数定义在Canvas中,参照下面。 
     * save()方法默认的是还原matrix和clip,可是可使用这个方法指定哪些须要还原。而且只有指定matrix和clip才有效,其他的几个参数是 
     * 用于saveLayer()和saveLayerAlpha()方法 的。 
     */  
    public native int save(int saveFlags);  
  
  
    /** 
     * 回到上一个save调用以前的状态,若是restore调用的次数大于save方法,会出错。 
     */  
    public native void restore();  
  
     /** 
     * 返回栈中保存的状态,值等译 save()调用次数-restore()调用次数 
     */  
    public native int getSaveCount();  
    
  
    /** 
     * 回到任何一个save()方法调用以前的状态 
     */  
    public native void restoreToCount(int saveCount);  
  
  
  
  /**saveFlags的参数*/  
 public static final int MATRIX_SAVE_FLAG = 0x01;//须要还原Matrix  
 public static final int CLIP_SAVE_FLAG = 0x02;//须要还原Clip  
      
  public static final int HAS_ALPHA_LAYER_SAVE_FLAG = 0x04;  
  public static final int FULL_COLOR_LAYER_SAVE_FLAG = 0x08;  
  public static final int CLIP_TO_LAYER_SAVE_FLAG = 0x10;  
  public static final int ALL_SAVE_FLAG = 0x1F; //还原全部  
  
 /*saveLayer*/  
 public int saveLayer(RectF bounds, Paint paint, int saveFlags)  
 
 public int saveLayer(float left, float top, float right, float bottom,  Paint paint, int saveFlags) 
   
 public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) 
  
 public int saveLayerAlpha(float left, float top, float right, float bottom,  int alpha, int saveFlags)


 




saveLayer

Canvas 在通常的状况下能够看做是一张画布,全部的绘图操做如drawBitmap, drawCircle都发生在这张画布上,这张画板还定义了一些属性好比Matrix,颜色等等。可是若是须要实现一些相对复杂的绘图操做,好比多层动画,地图(地图能够有多个地图层叠加而成,好比:政区层,道路层,兴趣点层)。Canvas提供了图层(Layer)支持,缺省状况能够看做是只有一个图层Layer。若是须要按层次来绘图,Android的Canvas可使用SaveLayerXXX, Restore 来建立一些中间层,对于这些Layer是按照“栈结构“来管理的:       


 建立一个新的Layer到“栈”中,可使用saveLayer, savaLayerAlpha, 从“栈”中推出一个Layer,可使用restore,restoreToCount。但Layer入栈时,后续的DrawXXX操做都发生在这个Layer上,而Layer退栈时,就会把本层绘制的图像“绘制”到上层或是Canvas上,在复制Layer到Canvas上时,能够指定Layer的透明度(Layer),这是在建立Layer时指定的:public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags)本例Layers 介绍了图层的基本用法:Canvas能够看作是由两个图层(Layer)构成的,为了更好的说明问题,咱们将代码稍微修改一下,缺省图层绘制一个红色的圆,在新的图层画一个蓝色的圆,新图层的透明度为0×88。      

public class Layers extends Activity {  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(new SampleView(this));  
    }  
  
    private static class SampleView extends View {  
        private static final int LAYER_FLAGS = Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG  
                | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG  
                | Canvas.CLIP_TO_LAYER_SAVE_FLAG;  
  
        private Paint mPaint;  
  
        public SampleView(Context context) {  
            super(context);  
            setFocusable(true);  
  
            mPaint = new Paint();  
            mPaint.setAntiAlias(true);  
        }  
  
        @Override  
        protected void onDraw(Canvas canvas) {  
            canvas.drawColor(Color.WHITE);    
            canvas.translate(10, 10);    
            mPaint.setColor(Color.RED);    
            canvas.drawCircle(75, 75, 75, mPaint);    
            canvas.saveLayerAlpha(0, 0, 200, 200, 0x88, LAYER_FLAGS);    
            mPaint.setColor(Color.BLUE);    
            canvas.drawCircle(125, 125, 75, mPaint);    
            canvas.restore();   
         }  
    }  
}


参考:http://blog.csdn.net/linghu_java/article/details/8939952

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息