Android 繪圖之Canvas相關(guān)API使用

Android 自定義控件或多或少都會用到Canvas,那么我們就需要熟悉它的API。Canvas給我們提供了大量的的DrawXXX方法,通過這些方法我們就可以繪制出我們想要的效果。接下來看看官方是怎么說的:

The Canvas class holds the "draw" calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint (to describe the colors and styles for the drawing).

大致意思就是說:
Canvas類持有“draw”調(diào)用。 要繪制一些東西瘦赫,你需要4個基本組件:一個位圖來保存像素,一張畫布(Canvas)來主持繪圖調(diào)用(寫入位圖)啸箫,一個繪圖圖元(如Rect耸彪,Path,text忘苛,Bitmap)和一支畫筆(描述繪圖的顏色和樣式)蝉娜。

首先介紹下畫筆(Paint)的常用API:

    private void initPaint() {
        // 設(shè)置最基本的屬性
        // 設(shè)置畫筆顏色
        // 可直接引入Color類,如Color.red等
        mPaint.setColor(int color);
        // 設(shè)置畫筆模式
        mPaint.setStyle(Style style);
        // Style有3種類型:
        // 類型1:Paint.Style.FILLANDSTROKE(描邊+填充)
        // 類型2:Paint.Style.FILL(只填充不描邊)
        // 類型3:Paint.Style.STROKE(只描邊不填充)
        //設(shè)置畫筆的粗細
        mPaint.setStrokeWidth(float width);
        // 如設(shè)置畫筆寬度為10px
        mPaint.setStrokeWidth(10f);
        
        // 不常設(shè)置的屬性
        // 得到畫筆的顏色     
        mPaint.getColor();
        // 設(shè)置Shader
        // 即著色器扎唾,定義了圖形的著色召川、外觀
        mPaint.setShader(Shader shader);
        //設(shè)置畫筆的a,r,p,g值
        mPaint.setARGB(int a, int r, int g, int b);
        //設(shè)置透明度
        mPaint.setAlpha(int a);
        //得到畫筆的Alpha值
        mPaint.getAlpha();
        
        // 對字體進行設(shè)置(大小、顏色)
        //設(shè)置字體大小
        mPaint.setTextSize(float textSize)
        // 設(shè)置對齊方式   
        mPaint.setTextAlign(Algin algin);
        // LEFT:左對齊
        // CENTER:居中對齊
        // RIGHT:右對齊
        //設(shè)置文本的下劃線
        mPaint.setUnderlineText(boolean underlineText);
        //設(shè)置文本的刪除線
        mPaint.setStrikeThruText(boolean strikeThruText);
        //設(shè)置文本粗體
        mPaint.setFakeBoldText(boolean fakeBoldText);
        // 設(shè)置斜體
        mPaint.setTextSkewX(-0.5f);
        // 設(shè)置文字陰影
        mPaint.setShadowLayer(5,5,5,Color.YELLOW);
    }

Paint默認的字體大小為12px胸遇,在繪制文本時我們往往要考慮密度density設(shè)置合適的字體大小荧呐。畫筆的默認顏色為黑色,默認的style為FILL纸镊,默認的cap為BUTT倍阐,默認的線寬為0。

一 坐標(biāo)系

  • Canvas坐標(biāo)系
    Canvas坐標(biāo)系即Canvas本身的坐標(biāo)系逗威。Canvas坐標(biāo)原點(0,0)在View的左上角峰搪,向右為X軸正方向,向下為Y軸正方向凯旭。Canvas坐標(biāo)系唯一且不會改變概耻。
  • 繪圖坐標(biāo)系
    繪圖坐標(biāo)系區(qū)別于Canvas坐標(biāo)系,以我們繪圖起始點為坐標(biāo)原點(0,0)罐呼,繪圖坐標(biāo)系默認與Canvas坐標(biāo)系重合鞠柄。繪圖坐標(biāo)系原點位置可以更改,Canvas的 translate嫉柴、rotate厌杜、scale 操作都是基于繪圖坐標(biāo)系變化。
    //繪制坐標(biāo)系
    private void drawAxis(Canvas canvas) {
        int width = canvas.getWidth();
        int height = canvas.getHeight();
        int translate = width / 5;

        //設(shè)置畫筆寬度
        mPaint.setStrokeWidth(10);
        //設(shè)置筆觸樣式
        mPaint.setStrokeCap(Paint.Cap.ROUND);

        //繪制默認繪圖坐標(biāo)系(此時與Canvas坐標(biāo)系重合)
        //繪制紅色X軸
        mPaint.setColor(Color.RED);
        canvas.drawLine(0, 0, width, 0, mPaint);
        //繪制藍色Y軸
        mPaint.setColor(Color.BLUE);
        canvas.drawLine(0, 0, 0, height, mPaint);

        //平移
        canvas.translate(translate, translate);
        //繪制平移后繪圖坐標(biāo)系
        //繪制紅色X軸
        mPaint.setColor(Color.RED);
        canvas.drawLine(0, 0, width, 0, mPaint);
        //繪制藍色Y軸
        mPaint.setColor(Color.BLUE);
        canvas.drawLine(0, 0, 0, height, mPaint);

        //平移 旋轉(zhuǎn)30度
        canvas.translate(translate, translate);
        canvas.rotate(30);

        //繪制平移旋轉(zhuǎn)后繪圖坐標(biāo)系
        //繪制紅色X軸
        mPaint.setColor(Color.RED);
        canvas.drawLine(0, 0, width, 0, mPaint);
        //繪制藍色Y軸
        mPaint.setColor(Color.BLUE);
        canvas.drawLine(0, 0, 0, height, mPaint);
    }

二 Canvas繪制顏色

單一顏色填充Canvas畫布

  • drawColor
  • drawRGB
  • drawARGB
    //繪制畫布顏色
    private void drawCanvasColor(Canvas canvas) {
        //drawARGB
        canvas.drawARGB(255, 47, 140, 150);
    }

三 繪制點

  • drawPoint 繪制點
  • drawPoints 繪制一組點
    //繪制點
    private void drawPoint(Canvas canvas) {
        int width = canvas.getWidth();
        int height = canvas.getHeight();
        int translateY = height/5;

        //設(shè)置畫筆顏色
        mPaint.setColor(Color.RED);
        //設(shè)置畫筆寬度
        mPaint.setStrokeWidth(200);

        //設(shè)置筆觸樣式
        mPaint.setStrokeCap(Paint.Cap.BUTT);
        //保存當(dāng)前畫布狀態(tài)(坐標(biāo)系)
        canvas.save();
        canvas.drawPoint(width / 3, height / 3, mPaint); 
        //恢復(fù)上次畫布保存狀態(tài)(坐標(biāo)系)
        canvas.restore();

        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setColor(Color.GREEN);
        canvas.save();
        canvas.translate(0, translateY);
        canvas.drawPoint(width / 3, height / 3, mPaint);
        canvas.restore();

        mPaint.setStrokeCap(Paint.Cap.SQUARE);
        mPaint.setColor(Color.BLUE);
        canvas.save();
        canvas.translate(translateY, translateY);
        canvas.drawPoint(width / 3, height / 3, mPaint);
        canvas.restore();
    }

四 繪制線

  • drawLine 繪制線
  • drawLines 繪制一組線
    //繪制線
    private void drawLine(Canvas canvas) {
        int width = canvas.getWidth();
        int height = canvas.getHeight();
        int startX = width / 5;
        int startY = height / 5;

        //設(shè)置畫筆顏色
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(20);
        //設(shè)置筆觸樣式
        mPaint.setStrokeCap(Paint.Cap.BUTT);
        //畫筆觸為BUTT的線
        canvas.drawLine(startX, startY, width - startX, startY, mPaint);

        //向下平移20
        canvas.translate(0, 60);

        mPaint.setColor(Color.GREEN);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        //畫筆觸為ROUND的線
        canvas.drawLine(startX, startY, width - startX, startY, mPaint);

        canvas.translate(0, 60);

        mPaint.setColor(Color.BLUE);
        mPaint.setStrokeCap(Paint.Cap.SQUARE);
        //畫筆觸為SQUARE的線
        canvas.drawLine(startX, startY, width - startX, startY, mPaint);

        canvas.translate(0, 80);

        mPaint.setColor(Color.BLACK);
        float[] pts = new float[]{startX, startY, width - startX, startY, startX, startY + 60, width - startX, startY + 60};
        canvas.drawLines(pts, mPaint);
    }

五 繪制矩形

  • drawRect 繪制矩形
  • drawRoundRect 繪制圓角矩形
    //繪制矩形
    private void drawRect(Canvas canvas) {
        int width = canvas.getWidth();
        int height = canvas.getHeight();

        //設(shè)置畫筆顏色
        mPaint.setColor(Color.RED);
        //設(shè)置畫筆寬度
        mPaint.setStrokeWidth(16);
        //設(shè)置畫筆樣式
        mPaint.setStyle(Paint.Style.FILL);

        canvas.drawRect(20, 20, 400, 200, mPaint);
        //繪制矩形 API21
        //canvas.drawRoundRect(220, 220, 400, 400, 10, 10, mPaint);
        RectF rect = new RectF(20, 420, 800, 600);
        canvas.drawRoundRect(rect, 10, 10, mPaint);

        mPaint.setColor(Color.BLUE);
        mPaint.setStyle(Paint.Style.STROKE);

        canvas.drawRect(20, 800, 400, 1000, mPaint);
        RectF rect1 = new RectF(20, 1200, 800, 1400);
        canvas.drawRoundRect(rect1, 10, 10, mPaint);
    }

六 繪制圓

  • drawCircle 繪制圓
    //繪制圓形
    private void drawCircle(Canvas canvas) {
        int width = canvas.getWidth();
        int height = canvas.getHeight();
        int halfWidth = width / 2;
        int d = height / 3;
        int r = d / 2 - 10;

        //設(shè)置畫筆顏色
        mPaint.setColor(Color.RED);
        //設(shè)置畫筆寬度
        mPaint.setStrokeWidth(2);
        //設(shè)置畫筆樣式
        mPaint.setStyle(Paint.Style.FILL);

        //繪制圓
        canvas.drawCircle(halfWidth, (float) (d * 0.5), r, mPaint);

        //繪制兩個圓實現(xiàn)圓環(huán)效果
        mPaint.setColor(Color.GREEN);
        canvas.drawCircle(halfWidth, (float) (d * 1.5), r, mPaint);
        mPaint.setColor(Color.WHITE);
        canvas.drawCircle(halfWidth, (float) (d * 1.5), r - 40, mPaint);

        //繪制一個圓實現(xiàn)圓環(huán)效果
        mPaint.setStrokeWidth(40);
        mPaint.setColor(Color.BLUE);
        mPaint.setStyle(Paint.Style.STROKE);
        //半徑減去畫筆畫筆寬度的一半 圓的大小和前面一致
        canvas.drawCircle(halfWidth, (float) (d * 2.5), r - 20, mPaint);
    }

七 繪制橢圓

  • drawOval 繪制橢圓
    跟繪制圓差不多计螺,唯一不同就是繪制圓是指定圓心和半徑夯尽,繪制橢圓是指定左上右下4個距離侧馅。
    //繪制橢圓 
    private void drawOval(Canvas canvas) {
        //設(shè)置畫筆顏色
        mPaint.setColor(Color.RED);
        //設(shè)置畫筆寬度
        mPaint.setStrokeWidth(2);
        //設(shè)置畫筆樣式
        mPaint.setStyle(Paint.Style.FILL);
        RectF overRect = new RectF(20, 20, 400, 200);
        canvas.drawOval(overRect, mPaint);
        
        mPaint.setColor(Color.GREEN);
        mPaint.setStrokeWidth(20);
        mPaint.setStyle(Paint.Style.STROKE);
        overRect = new RectF(20, 220, 200, 600);
        canvas.drawOval(overRect, mPaint);
    }

八 繪制圓弧

  • drawArc 繪制弧
    繪制圓弧,可以繪制弧面和弧線呐萌。弧面即用弧圍成的填充面谊娇,弧線即為弧面的輪廓線肺孤。
    //繪制弧
    private void drawAcr(Canvas canvas) {
        int width = canvas.getWidth();
        
        //設(shè)置畫筆顏色
        mPaint.setColor(Color.RED);
        //設(shè)置畫筆寬度
        mPaint.setStrokeWidth(2);
        //設(shè)置畫筆樣式
        mPaint.setStyle(Paint.Style.FILL);
        //和前面繪制橢圓的矩形一致(正方形也可)
        RectF arcRect = new RectF(20, 20, 400, 200);
        //根據(jù)矩形繪制弧形 開始角度0 掃過角度360 通過中心點首尾連接:true
        // 和前面繪制的橢圓效果一致
        canvas.drawArc(arcRect, 0, 360, true, mPaint);

        canvas.translate(0, width / 5);
        canvas.drawArc(arcRect, 0, 90, true, mPaint);

        canvas.translate(0, width / 5);
        canvas.drawArc(arcRect, 0, 90, false, mPaint);

        //正方形
        arcRect = new RectF(20, 20, 220, 220);
        mPaint.setStrokeWidth(4);
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.translate(0, width / 5);
        //根據(jù)矩形繪制弧形 角度從0-1800 首尾連接
        canvas.drawArc(arcRect, 0, 180, true, mPaint);

        canvas.translate(0, width / 5);
        //根據(jù)矩形繪制弧形 角度從0-1800 首尾不連接
        canvas.drawArc(arcRect, 0, 180, false, mPaint);

        mPaint.setStrokeWidth(10);
        canvas.translate(width / 2, width / 5);
        //drawArc繪制出圓環(huán)
        canvas.drawArc(arcRect, 0, 270, false, mPaint);
        mPaint.setColor(Color.GREEN);
        canvas.drawArc(arcRect, 270, 90, false, mPaint);
    }

九 繪制文字

  • drawText 繪制文本
  • drawPosText 根據(jù)位置繪制文本
  • drawTextOnPath 根據(jù)路徑繪制文本
    //繪制文字
    private void drawText(Canvas canvas) {
        int width = canvas.getWidth();
        int height = canvas.getHeight();
        int textHeight = 32;
        int halfWidth = width / 2;

        //設(shè)置畫筆顏色
        mPaint.setColor(Color.GRAY);
        //設(shè)置畫筆寬度
        mPaint.setStrokeWidth(2);
        canvas.drawLine(halfWidth, 0, halfWidth, height, mPaint);

        mPaint.setColor(Color.BLACK);
        //設(shè)置文本大小
        mPaint.setTextSize(textHeight);
        //繪制普通文本
        canvas.drawText("繪制普通文本", 0, textHeight, mPaint);

        mPaint.setColor(Color.RED);
        mPaint.setTextAlign(Paint.Align.LEFT);
        //存儲畫布狀態(tài) 坐標(biāo)系
        canvas.save();
        //平移
        canvas.translate(halfWidth, textHeight);
        //繪制左對齊文本
        canvas.drawText("繪制左對齊文本", 0, textHeight, mPaint);
        //恢復(fù)上次存儲狀態(tài)
        canvas.restore();

        mPaint.setColor(Color.GREEN);
        mPaint.setTextAlign(Paint.Align.CENTER);
        //存儲畫布狀態(tài) 坐標(biāo)系
        canvas.save();
        //平移
        canvas.translate(halfWidth, textHeight * 2);
        //繪制居中對齊文本(對齊是根據(jù)繪圖坐標(biāo)系而言)
        canvas.drawText("繪制居中對齊文本", 0, textHeight, mPaint);
        //恢復(fù)上次存儲狀態(tài)
        canvas.restore();

        mPaint.setColor(Color.BLUE);
        mPaint.setTextAlign(Paint.Align.RIGHT);
        //存儲畫布狀態(tài) 坐標(biāo)系
        canvas.save();
        //平移
        canvas.translate(halfWidth, textHeight * 3);
        //繪制右對齊文本
        canvas.drawText("繪制右對齊文本", 0, textHeight, mPaint);
        //恢復(fù)上次存儲狀態(tài)
        canvas.restore();


        mPaint.setColor(Color.BLACK);
        //恢復(fù)默認對齊方式
        mPaint.setTextAlign(Paint.Align.LEFT);
        //設(shè)置下劃線
        mPaint.setUnderlineText(true);
        //設(shè)置加粗
        mPaint.setFakeBoldText(true);
        //設(shè)置刪除線
        mPaint.setStrikeThruText(true);
        //存儲畫布狀態(tài) 坐標(biāo)系
        canvas.save();
        //平移
        canvas.translate(halfWidth, textHeight * 4);
        //繪制下劃線加粗文本
        canvas.drawText("繪制下劃線加粗文本", 0, textHeight, mPaint);
        //恢復(fù)上次存儲狀態(tài)
        canvas.restore();

        mPaint.reset();
        mPaint.setColor(Color.BLACK);
        //設(shè)置文本大小
        mPaint.setTextSize(textHeight);
        //存儲畫布狀態(tài) 坐標(biāo)系
        canvas.save();
        canvas.translate(width / 3, height / 3);
        //旋轉(zhuǎn)
        canvas.rotate(45);
        //繪制傾斜文本
        canvas.drawText("繪制傾斜文本", 0, textHeight, mPaint);
        //恢復(fù)上次存儲狀態(tài)
        canvas.restore();

                float[] pos = new float[]{40, 40, 80, 80, 120, 120, 160, 160, 200, 200, 240, 240};
        //存儲畫布狀態(tài) 坐標(biāo)系
        canvas.save();
        canvas.translate(width / 3, height / 2);
        canvas.drawPosText("繪制位置文本", pos, mPaint);
        //恢復(fù)上次存儲狀態(tài)
        canvas.restore();

        Path path = new Path();
        path.cubicTo(550, 750, 350, 250, 850, 800);
        //畫路徑
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.drawPath(path,mPaint);
        canvas.drawTextOnPath("繪制文本OnPath繪制文本OnPath繪制文本OnPath繪制文本OnPath繪制文本OnPath", path, 50, 0, mPaint);
    }

十 繪制Path

  • drawPath 繪制路徑
    //path拐點集合
    List<Point> points = new ArrayList<>();

    //繪制Path
    private void drawPath(Canvas canvas) {
        int width = canvas.getWidth();
        int height = canvas.getHeight();
        int deltaX = width / 4;
        int deltaY = (int) (deltaX * 0.75);

        //設(shè)置畫筆顏色
        mPaint.setColor(Color.GRAY);
        //設(shè)置畫筆寬度
        mPaint.setStrokeWidth(4);

        //Fill模式畫面
        Path path1 = new Path();
        RectF arcRect = new RectF(0, 0, deltaX, deltaY);
        path1.addArc(arcRect, 0, 360);
        path1.addRect(deltaX, 0, deltaX << 1, deltaY, Path.Direction.CW);
        canvas.drawPath(path1, mPaint);

        //STROKE模式畫線
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.translate(0, deltaY << 1);
        canvas.drawPath(path1, mPaint);

        mPaint.setColor(Color.BLUE);
//        mPaint.setStyle(Paint.Style.FILL);
        canvas.translate(0, deltaY << 1);

        Path path2 = new Path();
        path2.lineTo(100, 0);   //畫線
        points.add(new Point(100, 0));  //終點 X: 100 Y: 0

        RectF overRect = new RectF(100, -50, 300, 50);
        path2.arcTo(overRect, 180, -90); //畫橢圓 左下部分
        points.add(new Point(200, 50)); //終點 X: 250 Y: 50

        overRect = new RectF(200, 0, 400, 100);
        path2.arcTo(overRect, 180, 90); //畫橢圓右上部分
        points.add(new Point(300, 0));  //終點 X: 300 Y: 0

        path2.lineTo(350, 50);  //畫線
        points.add(new Point(350, 50)); //終點 X: 350 Y: 50

        //畫二階貝塞爾曲線 第一個坐標(biāo)為控制點 最后為終點
        path2.quadTo(450, -50, 500, 150);
        points.add(new Point(500, 150)); //終點 X: 500 Y: 150

        //畫三階階貝塞爾曲線 前兩個坐標(biāo)為控制點 最后為終點
        path2.cubicTo(600, 150, 700, 0, 380, -200);
        points.add(new Point(380, -200)); //終點 X: 480 Y: -200

        path2.rLineTo(0, 100);
        points.add(new Point(380, -200 + 100)); //終點 X: 480 Y: -100
        canvas.drawPath(path2, mPaint);

        mPaint.setStrokeWidth(10);
        mPaint.setColor(Color.RED);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        for (Point point : points) {
            canvas.drawPoint(point.x, point.y, mPaint);
        }
    }

十一 繪制Bitmap

  • drawBitmap 繪制Bitmap
    //繪制Bitmap
    private void drawBitmap(Canvas canvas) {
        BitmapDrawable drawable = (BitmapDrawable) getResources().getDrawable(R.mipmap.ic_launcher);
        Bitmap bitmap = drawable.getBitmap();

        //如果bitmap不存在,那么就不執(zhí)行下面的繪制代碼
        if (bitmap == null) {
            return;
        }
        //直接完全繪制Bitmap
        canvas.drawBitmap(bitmap, 0, 0, mPaint);

        //繪制Bitmap的一部分济欢,并對其拉伸
        //srcRect定義了要繪制Bitmap的哪一部分
        Rect srcRect = new Rect();
        srcRect.left = 0;
        srcRect.right = bitmap.getWidth();
        srcRect.top = 0;
        srcRect.bottom = (int) (0.33 * bitmap.getHeight());
        float radio = (float) (srcRect.bottom - srcRect.top) / bitmap.getWidth();
        //dstRecF定義了要將繪制的Bitmap拉伸到哪里
        RectF dstRecF = new RectF();
        dstRecF.left = 0;
        dstRecF.right = canvas.getWidth();
        dstRecF.top = bitmap.getHeight();
        float dstHeight = (dstRecF.right - dstRecF.left) * radio;
        dstRecF.bottom = dstRecF.top + dstHeight;
        canvas.drawBitmap(bitmap, srcRect, dstRecF, mPaint);
    }

以上就是大部分的繪制操作赠堵,當(dāng)然還有一些沒介紹到,還有一些需要在API21(5.0)以上才能使用法褥,這個使用到的時候可以弄個小demo看下效果茫叭,接下來介紹下針對畫布變換和畫布裁剪做一些介紹。

十二 畫布變換

  • translate 平移
  • scale 縮放
  • rotate 旋轉(zhuǎn)
  • skew 錯切

在學(xué)習(xí)繪制操作的時候很多地方都使用到了translate 和rotate 這里就不再對它們進行操作

1.畫布scale

    //畫布縮放
    private void canvasScale(Canvas canvas) {
        int width = canvas.getWidth();
        int height = canvas.getHeight();
        int hWidth = width / 2;
        int hHeight = height / 2;

        mPaint.setColor(Color.GRAY);
        mPaint.setStrokeWidth(2);
        mPaint.setStyle(Paint.Style.STROKE);
        //使用path 畫布中心的X Y 軸
        Path path = new Path();
        path.moveTo(hWidth, 0);
        path.lineTo(hWidth, height);
        path.moveTo(0, hHeight);
        path.lineTo(width, hHeight);
        canvas.drawPath(path, mPaint);

        //畫布平移
        canvas.translate(hWidth, hHeight);

        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(5);
        RectF rectF = new RectF(0, 0, 200, 100);
        canvas.drawRect(rectF, mPaint);

        //默認0,0進行縮放
        canvas.scale(1.5f, 1.5f);
        mPaint.setColor(Color.BLUE);
        canvas.drawRect(rectF, mPaint);

        //100,0進行縮放
        canvas.scale(1.5f, 1.5f, 100, 0);
        mPaint.setColor(Color.GREEN);
        canvas.drawRect(rectF, mPaint);

        /*
        當(dāng)縮放倍數(shù)為負數(shù)時半等,會先進行縮放揍愁,然后根據(jù)不同情況進行圖形翻轉(zhuǎn):
        (設(shè)縮放倍數(shù)為(a,b),旋轉(zhuǎn)中心為(px杀饵,py)):
        a<0莽囤,b>0:以px為軸翻轉(zhuǎn)
        a>0,b<0:以py為軸翻轉(zhuǎn)
        a<0切距,b<0:以旋轉(zhuǎn)中心翻轉(zhuǎn)
         */
        //100,0進行縮放 以Y軸翻轉(zhuǎn)
        canvas.scale(1f, -1f, 100, 0);
        mPaint.setColor(Color.BLACK);
        canvas.drawRect(rectF, mPaint);
    }

2.畫布skew

    //畫布錯切
    private void canvasSkew(Canvas canvas) {
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(5);
        mPaint.setStyle(Paint.Style.STROKE);
        RectF rectF = new RectF(0, 0, 400, 200);
        canvas.translate(100,100);
        canvas.drawRect(rectF, mPaint);

        canvas.save();
        canvas.translate(0,300);
        //畫布X正方向錯切45°
        canvas.skew(1f, 0);
        canvas.drawRect(rectF, mPaint);
        canvas.restore();

        canvas.save();
        canvas.translate(0,600);
        //畫布Y負方向錯切45°
        canvas.skew(0, -1f);
        canvas.drawRect(rectF, mPaint);
        canvas.restore();
        
        mPaint.setColor(Color.GREEN);
        canvas.drawLine(0,400,600,400,mPaint);
    }

十三 畫布裁剪

  • clipPath
  • clipRect
  • clipRegion(過時)
  • getClipBounds
    //畫布裁剪
    private void canvasClip(Canvas canvas) {
        canvas.drawColor(Color.RED);
        canvas.save();
        //矩形裁剪
        canvas.clipRect(0, 0, 400, 200);
        canvas.drawColor(Color.BLUE);
        canvas.restore();

        canvas.save();
        canvas.translate(20, 400);
        Path path = new Path();
        path.addRect(0, 0, 400, 200, Path.Direction.CCW);
        canvas.drawPath(path, mPaint);
        //路徑裁剪
        canvas.clipPath(path);
        canvas.drawColor(Color.GREEN);
        //獲得裁剪邊界
        Rect bounds = canvas.getClipBounds();
        mPaint.setColor(Color.BLACK);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(10);
        canvas.drawRect(bounds, mPaint);
        canvas.restore();
    }

這里針對Canvas的API進行了一些說明朽缎,希望對大家有所幫助。沒有添加完整工程上來谜悟,但是每一個方法都是實際跑過的话肖,只需要在onDraw中調(diào)用就可以看到效果了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末葡幸,一起剝皮案震驚了整個濱河市最筒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌礼患,老刑警劉巖是钥,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異缅叠,居然都是意外死亡悄泥,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門肤粱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來弹囚,“玉大人,你說我怎么就攤上這事领曼∨葛模” “怎么了蛮穿?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長毁渗。 經(jīng)常有香客問我践磅,道長,這世上最難降的妖魔是什么灸异? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任府适,我火速辦了婚禮,結(jié)果婚禮上肺樟,老公的妹妹穿的比我還像新娘檐春。我一直安慰自己,他們只是感情好么伯,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布疟暖。 她就那樣靜靜地躺著,像睡著了一般田柔。 火紅的嫁衣襯著肌膚如雪俐巴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天凯楔,我揣著相機與錄音窜骄,去河邊找鬼。 笑死摆屯,一個胖子當(dāng)著我的面吹牛邻遏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播虐骑,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼准验,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了廷没?” 一聲冷哼從身側(cè)響起糊饱,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎颠黎,沒想到半個月后另锋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡狭归,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年夭坪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片过椎。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡室梅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情亡鼠,我是刑警寧澤赏殃,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站间涵,受9級特大地震影響仁热,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜勾哩,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一股耽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧钳幅,春花似錦、人聲如沸炎滞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽册赛。三九已至钠导,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間森瘪,已是汗流浹背牡属。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留扼睬,地道東北人逮栅。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像窗宇,于是被迫代替她去往敵國和親措伐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容