android canvas(Android绘图基础--Canvas和Drawable)

:暂无数据 2026-03-31 06:40:01 0
我们注意到,那些在android canvas上表现突出的人,往往都对Android绘图基础--Canvas和Drawable有独到的见解。这并非巧合。

本文目录

Android绘图基础--Canvas和Drawable

Github链接

画2D图形有两种方法:

Canvas实际上是封装了各种draw方法的类,调用draw方法把图形绘制到底层的Su***ce上,即绘制在Window上。

这个例子中构造了两个Canvas和一个Bitmap,分别调用其draw方法,先是mCanvas往Bitmap里绘制一个方块,再在onDraw方法内调用canvas.drawBitmap绘制这个方块。

思考一个问题,为什么mCanvas需要设置Bitmap?

很简单,因为它没有持有一块内存地址,自然没法绘制。来看一下draw的起点ViewRootImpl(软件绘制,不开启硬件加速下)。

这个通过mSu***ce.lockCanvas返回的Canvas是View.draw的canvas变量,所以当1,2情况时,Canvas都持有一个Bitmap,指向共享内存里的某一小块,当调用Canvas.draw方法时就能绘制出东西。但对于自定义Canvas来说并不是,即使设置一个Bitmap和绘制了Bitmap,但不往共享内存上写,屏幕上是不会显示的,Su***ceView同理,通过Su***ce.lockCanvas获取持有共享内存的Canvas,绘制完毕后调用Su***ce.unlockCanvasAndPost把绘制内容显示到su***ce上并release掉Canvas。

顺带一提Canvas.save和Canvas.restore方法,如下Demo

效果图如

画的是三个颜色和旋转角度都不同的小方形。

步骤1把默认坐标系旋转20°,画出第一个蓝色的方形,步骤2保存当前的matrix(旋转了20°),继续旋转20°,此时坐标系已经旋转了40°,画出第二个黄色的方块,步骤3,恢复上一步保存的matrix(旋转了20°),此时坐标系还是旋转了20°,步骤4,再旋转40°,此时坐标系旋转了60°,画出第三个黑色方块。

Canvas.save用于保存当前matrix和clip,Canvas.restore用于恢复上次保存的matrix和clip。

Drawable是一个能画出来的物体的抽象,使用前需要调用setBounds确定位置和大小,通过getIntrinsicHeight和getIntrinsicWidth取到实际大小。Drawable可以有几种形式存在:Bitmap、Nine Patch、Vector、Shape、Layers等。

从Resource.getDrawable会判断是否.xml结尾,不是的话走6,7步,如果从xml中读取,需要getResource.getDrawable -》 ResourceImpl.loadDrawableForCookie -》 drawable.createFromXml -》 DrawableInflater.inflateFromXmlForDensity -》 drawable.inflateFromTag

看一下Shape实现类GradientDrawable的inflate实现,读取各项属性并赋值,到draw方法。

调用canvas.drawRect把mRect画出来,而mRect的赋值在ensureValidRect。

bounds在哪里设置的?答案是ImageView.updateDrawable内,会调用Drawable.getIntrinsicHeight赋值(从xml中size属性读取),再调用configureBounds -》 setBounds,如果使用的不是ImageView,一定要在draw之前 调用setBounds ,否则size就会出错。

回到loadDrawableForCookie,再看一下6,7步加载图片的过程,通过AssetManager读取图片流数据,通过Drawable.createFromResourceStream这个我们经常使用的方法获取到Drawable。

取到屏幕密度之后调用BitmapFactory.decodeResourcesStream,计算密度后调用native创建Bitmap,感兴趣的同学可以看下更具体的分析文章(如 理解Bitmap )。

本文探究了两点

Android 7.1.1 源码

Android 官方文档, Canvas and Drawable , Drawable 等

android canvas的drawText方法 如何设置字体大小和格式

Canvas相当于画布,字体的大小格式在Paint上设置才正确, Paint 相当于画笔。代码如下,没有具体参数:

Paint paint = new Paint();

paint.setTextSize(textSize);//设置字体大小

paint.setTypeface(typeface);//设置字体类型

canvas.drawText(text, x, y, paint);//使用画笔paint

@Override

public void onDraw (Canvas canvas) {

Rect targetRect = new Rect(50, 50, 1000, 200);

Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

paint.setStrokeWidth(3);

paint.setTextSize(80);

String testString = "测试:ijkJQKA:1234";

paint.setColor(Color.CYAN);

canvas.drawRect(targetRect, paint);

paint.setColor(Color.RED);

FontMetricsInt fontMetrics = paint.getFontMetricsInt();

扩展资料:

Screen Space - Camera

此模式类似Screen Space - Overlay,但区别是此模式将Canvas放置于某个Camera前固定距离。此Camera负责渲染所有UI元素,则摄像机参数(Camera Settings)直接影响UI表现。

比如Camera是透视模式(Perspective),则UI元素会基于Field of View的值而扭曲变形。同样的,若屏幕分辨率变更,或者视觉平截体(CameraFrustrum)改变,则Canvas自动调整自身尺寸作自适应。

android canvas 是像素吗

Canvas : 画布对象,相当于现实生活中画图用的 ‘纸 或 布’。
下面介绍来自于android学习手册,android学习手册包含9个章节,108个例子,源码文档随便看,例子都是可交互,可运行,源码采用android studio目录结构,高亮显示代码,文档都采用文档结构图显示,可以快速定位。360手机助手中下载,排在第三、四个。
Android画图最基本的三个对象(Color,Paint,Canvas)
三个类都存放在 android.graphics包下
1) Color :颜色对象,相当于现实生活中的 ‘调料’
2) Paint : 画笔对象,相当于现实生活中画图用的 ‘笔’————主要的还是对‘画笔’进行设置
3) Canvas : 画布对象,相当于现实生活中画图用的 ‘纸 或 布’
三者相结合,就能画出基本的图形

Android中canvas中drawText详解

安卓写自定义View中有一个类相信大家不会陌生,那就是Canvas。Canvas给我们调用者提供的api也很丰富。我们经常用到的画圆(drawCircle),画线(drawLine)。今天我们的要看的问题,是drawText(文字)。为什么要单独说画文字,因为安卓的drawText中,基线问题常常困扰我们,到底该怎么计算基线?正题开始:

2.再看图蓝色矩形框,来自于Paint中getFontMetrics方法中,大致意思是获取该字体的相关参数,参照api29文档 大致意思是,ascent 是单行字符距离基线的顶部最打值,top是所有字符距离基线的最高值,descent 是单行字符距离基线的底部最大值,bottom是所有字符距离基线的顶部最大值。

android怎么移动canvas

我们可以把这个Canvas理解成系统提供给我们的一块内存区域(但实际上它只是一套画图的API,真正的内存是下面的Bitmap),而且它还提供了一整套对这个内存区域进行操作的方法,所有的这些操作都是画图API。也就是说在这种方式下我们已经能一笔一划或者使用
Graphic来画我们所需要的东西了,要画什么要显示什么都由我们自己控制。
这种方式根据环境还分为两种:一种就是使用普通View的canvas画图,还有一种就是使用专门的Su***ceView的canvas来画图。两种的主要是区别就是可以在Su***ceView中定义一个专门的线程来完成画图工作,应用程序不需要等待View的刷图,提高性能。前面一种适合处理量比较小,帧率比较小的动画,比如说象棋游戏之类的;而后一种主要用在游戏,高品质动画方面的画图。
Paint 代表了Canvas上的画笔、画刷、颜料等等;
Paint类常用方法:
setARGB(int a, int r, int g, int b) // 设置 Paint对象颜色,参数一为alpha透明值
setAlpha(int a) // 设置alpha不透明度,范围为0~255
setAntiAlias(boolean aa) // 是否抗锯齿
setColor(int color) // 设置颜色,这里Android内部定义的有Color类包含了一些常见颜色定义
setTextScaleX(float scaleX) // 设置文本缩放倍数,1.0f为原始
setTextSize(float textSize) // 设置字体大小
setUnderlineText(booleanunderlineText) // 设置下划线
// 1、将会以颜色ARBG填充整个控件的Canvas背景
//mCanvas.drawARGB(122, 10, 159, 163) ;
// 2、将会以颜色ARBG填充整个控件的Canvas背景
//mCanvas.drawColor(Color.BLUE) ;
// 3、绘制颜色,但是要制定一个mode
//mCanvas.drawColor(Color.BLUE, Mode.SCREEN) ;
// 4、画背景,跟2等效
//mCanvas.drawPaint(mPaint) ;
// 5、画一个点
//mCanvas.drawPoint(23, 23, mPaint) ;
// 6、画很多点这里的float 表示{x0,y0,x1,y1,x2,y2,x3,y3.....}
//mCanvas.drawPoints(new float{10,11,10,12,10,13,10,14,10,15,10,16}, mPaint) ;
// 7、画线
//mCanvas.drawLine(...) ;
// 8、画长方形 Rect 和RectF的区别?
//精度不一样,Rect是使用int类型作为数值,RectF是使用float类型作为数值
//Rect r = new Rect(10,10,50,50) ;
//mCanvas.drawRect(r, mPaint) ;
//RectF rf = new RectF(10,10,50,50) ;
//mCanvas.drawRect(rf, mPaint) ;
//mCanvas.drawRect(10, 10, 50, 50, mPaint) ;
// 9、画椭圆 初始化RectF的参数是(left,top,right,bottom)
//RectF rf = new RectF(100,100 ,200 ,250) ;
//mCanvas.drawOval(rf, mPaint) ;
// 10、画圆 (圆心x0,圆心y0,半径,paint)
//mCanvas.drawCircle(100, 100, 50, mPaint) ;
// 11、画圆弧 RectF对象表明内切矩形的(left,top,right,bottom)
//RectF rf = new RectF(100 ,100 ,200 ,200) ;
// 参数(rf,startAngle ,angle ,sweepAngle ,paint) sweepAngle表明是否显示圆弧三角形 angle画多少度
//mCanvas.drawArc(rf, 60, 30, true, mPaint) ;
// 12、绘制圆角矩形 RectF是矩形的(left,top,right,bottom)
//RectF rf = new RectF(100 ,100 ,200 ,200) ;
// 50表明x方向的半径,20表示y方向的半径
//mCanvas.drawRoundRect(rf, 50, 20, mPaint) ;
// 13、画任意多边形
//Path path = new Path() ;
//path.moveTo(100, 100) ;
//path.lineTo(200, 200) ;
//path.lineTo(300, 200) ;
//mCanvas.drawPath(path, mPaint) ;
// 14、通过Path对象,也可以画其他的图形
//Path path = new Path() ;
//path.addCircle(100, 100, 20, Path.Direction.CCW) ;
//mCanvas.drawPath(path ,mPaint);
/*drawBitmap
drawText
drawPicture*/
/*Rect r = new Rect(100,100,200,200) ;
ByteArrayOutputStream out = new ByteArrayOutputStream();
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.bg) ;
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out) ;
InputStream in = new ByteArrayInputStream(out.toByteArray()) ;
*/
/*Picture picture = Picture.createFromStream(mContext.getResources().openRawResource(R.raw.bg)) ;
mCanvas.drawPicture(picture) ;*/
// 15、画bitmap对象
//mCanvas.drawBitmap(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.bg),100, 100, mPaint) ;
// 16、Matrix中包含了对Bitmap的处理操作
/*Matrix m = new Matrix() ;
m.postScale(2, 2) ;
m.postRotate(60) ;
mCanvas.drawBitmap(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.bg), m, mPaint) ;*/
// 17、画带Matrix参数的bitmap,经过Matrix对象可以对bitmap做相关的处理,比如旋转,缩放,移动等《关于Matrix的使用另行总结》
/*Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.bg) ;
Matrix m = new Matrix() ;
m.postScale(2, 2) ;
m.postRotate(60) ;
m.postTranslate(300, 300) ;
mCanvas.drawBitmap(bitmap, m, mPaint) ;*/
//mCanvas.drawBitmap(....) ; 暂不总结
// 18、画文字
//mCanvas.drawText(123, 10, 10, mPaint) ;
//mCanvas.drawText(....)

android绘图之Canvas基础(2)

Canvas画布,用于绘制出各种形状配合画布的变幻操作可以绘制出很多复杂图形,基本的绘制图形分类。
提供的绘制函数:

上面四个函数都可以绘制canvas的背景,注意到PorterDuff.Mode变量,它只对两个canvas绘制bitmap起作用,所以此处暂时不讨论mode参数(没有设置mode默认使用srcover porterduff mode)。

Rect 和RectF都是提供一个矩形局域。
(1)精度不一样,Rect是使用int类型作为数值,RectF是使用float类型作为数值。
(2)两个类型提供的方法也不是完全一致。

**
rect:RectF对象,一个矩形区域。
rx:x方向上的圆角半径。
ry:y方向上的圆角半径。
paint:绘制时所使用的画笔。**

**
cx 圆心x
cy 圆心y
radius半径**

需要一个Path,代表路径后面会讲解。

绘制线的集合,参数中pts是点的集合,两个值代表一个点,四个值代表一条线,互相之间不连接。
offset跳过的点,count跳过之后要绘制的点的总数,可以用于集合中部分点的绘制。

跳过部分节点:

没有跳过点

RectF oval:生成弧的矩形,中心为弧的圆心
float startAngle:弧开始的角度,以X轴正方向为0度,顺时针
float sweepAngle:弧持续的角度
boolean useCenter:是否有弧的两边,True,还两边,False,只有一条弧

在矩形框内画一个椭圆,如果是个正方形会画出一个圆。

canvas.drawPoint();
canvas.drawPoints();

**
只需要提供两个点一个坐标就可以绘制点。
canvas.drawPoint(20,20,mPaint);
float points = {30,40,40,50,60,60};
canvas.drawPoints(points,mPaint);**

这几种方法类似:
canvas.drawText("好好学习,天天向上",100,100,mPaint);

drawTextOnPath
沿着一条 Path 来绘制文字
text 为所需要绘制的文字
path 为文字的路径
hOffset 文字相对于路径的水平偏移量,用于调整文字的位置
vOffset 文字相对于路径竖直偏移量,用于调整文字的位置
值得注意的是,在绘制 Path 的时候,应该在拐弯处使用圆角,这样文字显示时更舒服

大致讲解,后面会重点讲解。

Rect src
Rect dst
其中src和dst这两个矩形区域是用来做什么的?
Rect src:指定绘制图片的区域
Rect dst或RectF dst:指定图片在屏幕上的绘制(显示)区域
首先指定图片区域,然后指定绘制图片的区域。

android绘图之Paint(1)
android绘图之Canvas基础(2)
Android绘图之Path(3)
Android绘图之drawText绘制文本相关(4)
Android绘图之Canvas概念理解(5)
Android绘图之Canvas变换(6)
Android绘图之Canvas状态保存和恢复(7)
Android绘图之PathEffect (8)
Android绘图之LinearGradient线性渐变(9)
Android绘图之SweepGradient(10)
Android绘图之RadialGradient 放射渐变(11)
Android绘制之BitmapShader(12)
Android绘图之ComposeShader,PorterDuff.mode及Xfermode(13)
Android绘图之drawText,getTextBounds,measureText,FontMetrics,基线(14)
Android绘图之贝塞尔曲线简介(15)
Android绘图之PathMeasure(16)
Android 动态修改渐变 GradientDrawable

Android绘图之Canvas变换(6)

前面讲解了Canvas的基本概念, Android绘图之Canvas概念理解(5) ,
对Canvas的概念进行了分析,但是没有说明和屏幕的关系,Canvas不等于屏幕,屏幕不会动的,我们也无法对屏幕进行(平移,缩放等)操作,只能对Canvas进行操作,所以对Canvas进行操作,屏幕不动,最终会导致看到的图像不同。

下面开始讲解Canvas的变幻操作:
包括:translate,rotate,scale,skew,clip,clipout,matrix

先从最简单的平移开始:

对Canvas进行平移,
dx: x轴方向进行平移,正值向屏幕右侧
dy:y轴方向进行平移,正值向屏幕下方

绘制两个点查看原点位置。

原点显然改变了,以后再绘制任何形状都是以translate后的原点开始绘制。

参数说明
sx:横向的缩放,默认为1,小数缩小,整数放大
sy:纵向的缩放,默认为1,小数缩小,整数放大

px,py,看源码知道是先translate,执行sx,sy然后再translate反方向。
第二次translate的坐标为(-px sx,-px sy),最终的效果就是px,py是缩放后不动的点。

缩放后坐标减半。

如果想控制缩放后的位置,如何控制呢,这就需要第二个函数。

还可以控制其他位置,例如控制缩放后在中心。

rotate有两个函数:
rotate(float degrees)
rotate(float degrees, float px, float py)
Degree:旋转的角度,正值为顺时针,负值为逆时针
Px,py:旋转的中心,如果不指定旋转中心默认为(0,0)点

指定旋转中心为矩形中心

参数说明:
sx:画布在x方向上倾斜相应的角度,sx倾斜角度的tan值,
sy:画布在y轴方向上倾斜相应的角度,sy为倾斜角度的tan值,

根据矩形或者路径裁剪画布,画布被切割之后,只有部分区域可用,其他区域无法绘制内容。
Clip函数切割的区域可用,clipOut未被切割的区域可用。(过时函数不再讲解)

Matrix提供了一些方法来控制变换:

android绘图之Paint(1)
android绘图之Canvas基础(2)
Android绘图之Path(3)
Android绘图之drawText绘制文本相关(4)
Android绘图之Canvas概念理解(5)
Android绘图之Canvas变换(6)
Android绘图之Canvas状态保存和恢复(7)
Android绘图之PathEffect (8)
Android绘图之LinearGradient线性渐变(9)
Android绘图之SweepGradient(10)
Android绘图之RadialGradient 放射渐变(11)
Android绘制之BitmapShader(12)
Android绘图之ComposeShader,PorterDuff.mode及Xfermode(13)
Android绘图之drawText,getTextBounds,measureText,FontMetrics,基线(14)
Android绘图之贝塞尔曲线简介(15)
Android绘图之PathMeasure(16)
Android 动态修改渐变 GradientDrawable

Android Canvas ClipPath锯齿问题

在开发一个Android自定义View的过程中,用到了自定义绘图,按照iOS平台的思维,我使用了Canvas 的 ClipPath方法(主要还是嫌直接计算路径太麻烦了,涉及到一大堆三角函数和分段函数)。但是最后的效果是锯齿严重,Paint对象设置了抗锯齿,Canvas也设置了抗锯齿,但是Clip之后就是有锯齿。经查找,可能是ClipPath的问题。最后只好采用了Path的op方法,通过Path的差集,合集等操作组合,才绘制出了满意的图形。

Android下通过Canvas类和Paint类画一个表格的方法的问题

Paint和Canvas类:
Paint:画笔,使用之前首先要调整好画笔,然后就可以在画布上绘图了,这样就可以显示在手机屏幕上。
主要方法有:setColor()
设置画笔的颜色
setTextSize()
设置字体大小
setStyle()
设置画笔的风格,空心还是实心
setStrokWidth()
设置空心的边框宽度
setTextAlign()
设置文字的对齐方式
setTypeface()
设置字体,如粗细、倾斜
在设置画笔颜色的时候,使用到了Color类,这个类定义了一些颜色常量和颜色转换。如Color.RED、Color.GRENN等,还可以通过Color类的静态方法rgb(int,int,int)
来定一个颜色,这三个参数的的值范围是0~255。
Canvas:是一个画布,可以在上面画想要的任何东西,也可以设置画布的一些的属性,比如背景颜色,尺寸等。Canvas提供了一下一些方法:
方法:Canvas(),创建一个空的画布,可以使用setBitmap()方法来设置绘制的具体画布;
Canvas(Bitmap
bitmap),以bitmap对象创建一个画布,此时则将内容绘制在bitmap上,bitmap不得为null.
drawColor(),设置画布的背景颜色。
drawRect(left,top,right,bottom,paint);画矩形,前四个是float,后一个是Paint类型。
drawLine(startX,startY,stopX,stopY,paint),画线,前四个参数是float,后一个是Paint类型。
drawText(text,x,y,paint);在画布上画指定的文本,x,y两个参数是float,后一个是Paint类型。

这篇文章就像一张关于android canvasAndroid绘图基础--Canvas和Drawable的思维导图,希望能帮你理清脉络。收藏起来,随时复习。
本文编辑:admin

更多文章:


pion是什么牌子的包包?“pron“是什么意思

pion是什么牌子的包包?“pron“是什么意思

你是否好奇,为什么人人都在谈pion?它和pion是什么牌子的包包之间究竟存在着怎样微妙的联系?答案就在下文。

2026年3月31日 07:40

position标签(哪些HTML标签有position属性)

position标签(哪些HTML标签有position属性)

还记得第一次接触position标签时的茫然吗?是哪些HTML标签有position属性这个概念,像一盏灯照亮了后续的路。本文将为你点亮这盏灯。

2026年3月31日 07:20

floor函数excel(excel随机数保留一位小数)

floor函数excel(excel随机数保留一位小数)

“floor函数excel”相关信息最新大全有哪些,这是大家都非常关心的,接下来就一起看看floor函数excel(excel随机数保留一位小数)!

2026年3月31日 07:00

android canvas(Android绘图基础--Canvas和Drawable)

android canvas(Android绘图基础--Canvas和Drawable)

我们注意到,那些在android canvas上表现突出的人,往往都对Android绘图基础--Canvas和Drawable有独到的见解。这并非巧合。

2026年3月31日 06:40

如何创建css文件(webstrom里面怎么新建css文件)

如何创建css文件(webstrom里面怎么新建css文件)

在了解如何创建css文件的过程中,您是否也曾对webstrom里面怎么新建css文件感到困惑?别担心,接下来我将结合常见场景,带您一步步理清其中的关键点。

2026年3月31日 06:20

9的二进制怎么算(十进制数9的二进制编码是什么)

9的二进制怎么算(十进制数9的二进制编码是什么)

大家好,如果您还对9的二进制怎么算不太了解,没有关系,今天就由本站为大家分享9的二进制怎么算的知识,包括十进制数9的二进制编码是什么的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!

2026年3月31日 06:00

sql select into from 用法(数据库中select into from 和 insert into select的区别)

sql select into from 用法(数据库中select into from 和 insert into select的区别)

还记得第一次接触sql select into from 用法时的茫然吗?是数据库中select into from 和 insert into select的区别这个概念,像一盏灯照亮了后续的路。本文将为你点亮这盏灯。

2026年3月31日 05:40

Linux重定向?C语言输入输出重定向

Linux重定向?C语言输入输出重定向

最新数据显示,关注重定向输入的人中,超过70%都对Linux重定向抱有浓厚兴趣。本文将满足这一核心需求。

2026年3月31日 05:20

java后端开发路线图(java学习零基础)

java后端开发路线图(java学习零基础)

本文旨在解决您关于java后端开发路线图的两大困惑:一是理清基本概念,二是深入解析java学习零基础。内容干练,直奔主题。

2026年3月31日 05:00

手机版个人简历(手机上能做个人简历吗)

手机版个人简历(手机上能做个人简历吗)

当我们讨论手机版个人简历时,我们真正需要关注的是什么?很多高手的答案都指向了:手机上能做个人简历吗。为什么?

2026年3月31日 04:40

最近更新

android canvas(Android绘图基础--Canvas和Drawable)
2026-03-31 06:40:01 浏览:0
sql select into from 用法(数据库中select into from 和 insert into select的区别)
2026-03-31 05:40:01 浏览:0
Linux重定向?C语言输入输出重定向
2026-03-31 05:20:01 浏览:0
热门文章

Linux重定向?C语言输入输出重定向
2026-03-31 05:20:01 浏览:0
标签列表