Android_2D绘图的学习Paint,Canvas(三)

前言

上一节,学习了Paint的高级用法后,这一节我们将canvas的用法。主要涉及到canvas的绘制坐标变换translate,rotate。还没看过上一节的请点击这里:Android_2D绘图的学习Paint,Canvas(二)

一,translate

translate在很多语言的图像处理中都存在,意思是平移,在canvas中,他表示平移坐标原点。比如说,你要在一个View的中心点画一个半径为r圆。你可以这样直接画:canvas.drawCircle(getWidth()/2,getHeight()/2,r,paint);也可以使用translate,先移动画布的坐标原点为view的中心:canvas.trandlate(getWidth()/2,getHeight()/2);然后再根据新的坐标画出圆即可:canvas.drawCircle(0,0,r,paint);这里起始点(0,0)就是view的中心。

二,rotate

rotate是旋转的意思,在canvas中,大家都说是旋转画布,其实更好理解的应该是旋转坐标。比如说,你先画一个图形,然后调用rotate方法,将会看到我们的图像没有被旋转。

这里我做了一个测试,先画一个蓝色的矩形,然后将画布rotate 30°,再画一个红色的矩形,根据上面的原理,应该是红色的被旋转了,而蓝色的则没有被旋转。那么事实呢,请看下图:

代码:

        //移动坐标原点为View中心
        canvas.translate(getWidth()/2, getHeight()/2);
        mPaint.setColor(Color.BLUE);
        mPaint.setStyle(Style.STROKE);
        //先画蓝色矩形
        canvas.drawRect(20, 0, 150, 100, mPaint);
        //旋转画布
        canvas.rotate(30);
        //再画红色矩形
        mPaint.setColor(Color.RED);
        canvas.drawRect(20, 0, 150, 100, mPaint);

我们看到正如我们说的一样,rotate只是旋转了画布的坐标。

三,save,restroe

save:用来保存Canvas的状态。save之后,可以调用Canvas的平移、放缩、旋转、错切、裁剪等操作。

restore:用来恢复Canvas之前保存的状态。防止save后对Canvas执行的操作对后续的绘制有影响。

这里画两个矩形来讲解使用方法,我们先绘制一个矩形,然后保存当前canvas坐标值,再旋转45度,画出一个同样的矩形,为了区分,颜色不一样,然后恢复canvas的坐标值,绘出x,y坐标。

效果:

代码:

// 矩形宽度
        int lenght = dp2px(120);
        canvas.translate(getWidth() / 2, getHeight() / 2);
        // 第一个黑色矩形
        canvas.drawRect(-lenght, -lenght, lenght, lenght, mPaint);
        // 保存x轴方向为3点钟方向的坐标
        canvas.save();
        // 旋转坐标轴
        canvas.rotate(45);
        mPaint.setColor(Color.BLUE);
        // 第二个蓝色矩形
        canvas.drawRect(-lenght, -lenght, lenght, lenght, mPaint);
        // 恢复坐标轴
        canvas.restore();
        mPaint.setColor(Color.RED);
        // 绘制坐标轴
        canvas.drawLine(0, 0, 300, 0, mPaint);
        canvas.drawText("x", 330, 0, textPaint);
        canvas.drawLine(0, 0, 0, 300, mPaint);
        canvas.drawText("y", 0, 330, textPaint);

这里当然save和restore是成对出现的,不然缺少意义,当然restore调用次数要少于save的调用次数。

四,简单的表盘

学会了translate,rotate,save,restore后,我们实践一下,绘制一个像这样的表盘:

看过这个简单表盘,都是由线,三角形,圆,文字绘出的,这些在前面都已经讲过,思路都在代码里,直接上代码:

    @Override
    protected void onDraw(Canvas canvas) {

        // 半径
        int radius = dp2px(100);
        // 修改坐标轴原点
        canvas.translate(getWidth() / 2, getHeight() / 2);
        // 保存坐标轴的状态
        canvas.save();
        // 画一个圆
        canvas.drawCircle(0, 0, radius, mPaint);
        // 逆时针旋转60度,这样 1 刻度就能在正确的位置
        canvas.rotate(-60);
        // 画出刻度:一共有60个刻度,从第一个刻度开始,每5个刻度为长刻度
        for (int i = 0; i < 60; i++) {
            if (i % 5 == 0) {
                // 绘制长刻度
                canvas.drawLine(radius, 0, radius + dp2px(20), 0, mPaint);
                /* 绘制数字,因为方向的问题,所以这里还需要旋转平移坐标轴 */
                // 保存-60的坐标轴
                canvas.save();
                // 将坐标轴移动到该画数字的位置
                canvas.translate(radius + dp2px(25), 0);
                // 旋转坐标,可以让数字朝向圆心
                canvas.rotate(90);
                String text = String.valueOf(i / 5 + 1);
                // 测量字体的宽度,使其居中
                int width = (int) textPaint.measureText(text);
                canvas.drawText(text, -width / 2, 0, textPaint);
                // 恢复后:坐标原点还是在View的中心,x轴方向为1点钟方向
                canvas.restore();
            } else {
                // 绘制短刻度
                canvas.drawLine(radius, 0, radius + dp2px(10), 0, mPaint);
            }
            canvas.rotate(360 / 60f);
        }
        // 恢复后:坐标原点还是在View的中心,x轴方向为3点钟方向
        canvas.restore();
        // 画出指针
        canvas.drawLine(0, 0, 0, -dp2px(60), mPaint);
        Path path = new Path();
        path.moveTo(3, -dp2px(60));
        path.lineTo(-3, -dp2px(60));
        path.lineTo(0, -dp2px(63));
        path.close();
        canvas.drawPath(path, mPaint);
        // 绘制文字
        String text = "canvas clock";
        int width = (int) textPaint.measureText(text);
        canvas.drawText(text, -width / 2, dp2px(50), textPaint);
    }

主要考虑一下数字方向的绘制,网上很多都没有考虑到这个问题。

时间: 2024-10-10 00:04:27

Android_2D绘图的学习Paint,Canvas(三)的相关文章

Android_2D绘图的学习Paint,Canvas(二)

前言 上一节,学会了Paint,Canvas的基本用法后,这一节,学习Paint的高级用法.还没看过上一节的请点击这里:Android_2D绘图的学习Paint,Canvas(一). 一,文字的绘制 在做UI的时候,常常会绘制文字,Canvas绘制文字时,主要考虑到字体的宽度和高度问题.字体的宽度比较好理解,这里我们主要考虑一下字体的高度. 先看一张图,网上搜的: 这里说明了在安卓中绘制字体时对于高度的划分:top,ascent,baseLine,descent,bottom.有点类似我们刚开始

Android_2D绘图的学习Paint,Canvas(一)

前言 安卓2D绘图,都是主要涉及到2个类:Paint,Canvas. 一,Paint Paint画笔,用于指定图形或者文字的颜色,大小等. 常用方法: setAntiAlias: 设置画笔的锯齿效果. setColor: 设置画笔颜色 setAlpha: 设置Alpha值 setTextSize: 设置字体尺寸. setStyle: 设置画笔风格,空心或者实心. setStrokeWidth: 设置空心的边框宽度. 1,HelloWorld 先从经典的helloworld开始,我们画出一个蓝色,

Cocos2d-x 3.1.1 学习笔记(三)学习绘图API

关于cocos2d-x 3.1.1 版本的绘图方法有两种 1.使用DrawNode类绘制自定义图形. 2.继承Layer类重写draw()方法. 以上两种方法都可以绘制自定义图形,根据自己的需要选择合适的方法. 一.使用DrawNode类绘制自定义图形 使用DrawNode 类绘制图形是最简单的方法,create一个DrawNode类,然后添加进场景.然后就可以愉快的绘图了. 1 auto s = Director::getInstance()->getWinSize(); 2 //创建 3 a

学习HTML5 canvas遇到的问题

学习HTML5 canvas遇到的问题 1. 非零环绕原则(nonzZero rule) 非零环绕原则是canvas在进行填充的时候是否要进行填充的判断依据. 在判断填充的区域拉一条线出来,拉到图形的外面,这条拉出来的线就是辅助线.判断绘制的线是否是从辅助线的左边穿过到辅助线的右边,此时这种穿过的方式记录为+1;如果是从辅助线的右边穿到辅助线的左边,就记做-1.最后将所有记录的数字进行求和,如果求和的结果为0,代表这块区域不要填充,否则,必须填充 上面的原理较难理解,可以这样理解,当在大矩形中绘

Android Path, Region, Paint, Canvas API篇

从这篇文章开始,准备学习Android Canvas相关的一些知识点,因为Canvas使用的时候还经常要用到Path,Region,Paint.所以这里我们先熟悉Path,Region,Paint,Canvas常用的一些API,为后续的学习做好准备. 在列出Path,Region,Paint,Canvas这些API之前先展示一个具体的实例.一个仪表盘.主要用到的是Canvas的API,和一些三角函数的运算.具体效果图如下 仪表盘分成了三段(2:1:2),每一段显示不同的颜色.刻度分成8大份每小份

转载《学习HTML5 canvas遇到的问题》

学习HTML5 canvas遇到的问题 1. 非零环绕原则(nonzZero rule) 非零环绕原则是canvas在进行填充的时候是否要进行填充的判断依据. 在判断填充的区域拉一条线出来,拉到图形的外面,这条拉出来的线就是辅助线.判断绘制的线是否是从辅助线的左边穿过到辅助线的右边,此时这种穿过的方式记录为+1;如果是从辅助线的右边穿到辅助线的左边,就记做-1.最后将所有记录的数字进行求和,如果求和的结果为0,代表这块区域不要填充,否则,必须填充 上面的原理较难理解,可以这样理解,当在大矩形中绘

cocos2dx游戏开发&mdash;&mdash;微信打飞机学习笔记(三)&mdash;&mdash;WelcomeScene的搭建

一.场景与层的关系: cocos2dx的框架可以说主要由导演,场景,层,精灵来构成: 1.其中导演,意如其名,就是操控整个游戏的一个单例,管理着整个游戏. 2.场景就像电影的一幕剧情,所以说,懂得如何划分好游戏的场景,是开始动手做游戏的第一步. 3.一个场景会有很多层,用来处理场景不同的功能. 4.而精灵则是最小的单位,比如子弹,飞机,敌机都是一个个的精灵所组成的.   二.WelcomeScene的搭建: 1.场景和层的二种搭建方法: (1)一种就是跟HelloWorld示例一样的方法,以一个

自定义View时,用到Paint Canvas的一些温故,讲讲平时一些效果是怎么画的(基础篇 二,图像遮盖,Canvas静态变化)

转载请注明出处:王亟亟的大牛之路 上一篇把简单的一些概念理一理,还画了个圈,那这一篇讲一下图像遮盖"Xfermode"和Canvas的旋转.平移等效果 Xfermode: AvoidXfermode 指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图). PixelXorXfermode 当覆盖已有的颜色时,应用一个简单的像素异或操作. PorterDuffXfermode 这是一个非常强大的转换模式,使用它,可以使用图像合成的16条Porter-Duff规则的任

自定义View时,用到Paint Canvas的一些温故,只有想不到没有做不到(实例 1,画一个简单的Activity并且实现他能实现的)

转载请注明出处:王亟亟的大牛之路 这两天都在写Paint Canvas 昨天前天都写的比较基础的一些只是和一些简单的Demo演示,那今天就写一个"大气磅礴的"(之前几篇没看的可以看下传送门:http://blog.csdn.net/ddwhan0123/article/details/50426935) 废话不多,先上效果 YE? 为什么贴2个一模一样的试图,你错了!不带toCopy按钮的那整个Activity都是画的,并且还有点击事件哦! 再贴一下2张图片(上面张为原图,下面一张为效