您的位置:首页 > 编程语言

anddroid 图形图像编程- 第二章 直线和曲线的绘制

2013-05-06 18:58 441 查看

2. 直线和曲线

本章主要描述两个基本问题:

(1) 如何使用画布绘制。

(2) 如何绘制基本的直线和曲线。

2.1 在画布上绘图

通常使用画布有两种情况,一种是通过继承android的view自定义自己的控件。这种情况下Canvas已经创建好,用户只需要在上边绘制即可,而绘制的结果会直接显示出来。

还有一种情况是用户需要创建自己的画布,绘制并保存,通常会将绘制的结果保存为位图。下面分别讨论这两种情况。

2.1.1 绘图基础

首先通过一个例子展示最基本的绘图接口的使用。

示例一种自定义了一个View并在其区域中显示了数条直线:

示例代码如下:

package com.example.androidgraphicsprogramm;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;

public
class
CanvasBasic extends Activity {

@Override
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}

privatestaticclassSampleViewextendsView {
private PaintmPaint;

public SampleView(Context context) {
super(context);
setFocusable(true);

mPaint=newPaint();

}

@Override protectedvoidonDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);

drawLine_1(canvas);
}

//
protected
void
drawLine_1(Canvas canvas) {
int xstart = 20;
int ystart = 100;
int linelen = 400;

//mPaint.setAntiAlias(true); //设置反锯齿
mPaint.setStrokeWidth(6);//线宽6个像素
mPaint.setColor(0xffff0000);//线的颜色为红色
mPaint.setTextSize(50);
mPaint.setStyle(Paint.Style.STROKE);

canvas.drawText("线宽为6,红色,字号50", xstart , ystart,mPaint);
ystart += 20;

canvas.drawLine(xstart, ystart,linelen + xstart , ystart,mPaint);
ystart += 20;

RectF r = new RectF();
r.left = xstart;
r.top = ystart + 10;
r.right = r.left + linelen/2;
r.bottom = r.top + linelen/2;
canvas.drawRect(r,
mPaint);

////////////////////////////////////////////////////////////////////////////

mPaint.setStrokeWidth(10);//线宽10个像素
mPaint.setColor(0xff00ff00);//线的颜色为绿色
mPaint.setTextSize(40);
mPaint.setStyle(Paint.Style.FILL);

ystart += (50 + linelen/2);

canvas.drawText("线宽为10,绿色,字号40", xstart , ystart,mPaint);
ystart += 20;

canvas.drawLine(xstart, ystart,linelen + xstart , ystart,mPaint);
ystart += 20;

r.left = xstart;
r.top = ystart + 10;
r.right = r.left + linelen/2;
r.bottom = r.top + linelen/2;
canvas.drawRect(r,
mPaint);

/////////////////////////////////////////////////////////////////////////////
mPaint.setStrokeWidth(10);//线宽10个像素
mPaint.setARGB(100,0, 255, 0);//线的颜色为绿色
mPaint.setTextSize(40);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);

ystart += (50 + linelen/2);

canvas.drawText("线宽为10,绿色,半透明", xstart , ystart,mPaint);
ystart += 20;

canvas.drawLine(xstart, ystart,linelen + xstart , ystart,mPaint);
ystart += 20;

r.left = xstart;
r.top = ystart + 10;
r.right = r.left + linelen/2;
r.bottom = r.top + linelen/2;
canvas.drawRect(r,
mPaint);
}
}
}
运行效果如图2-1所示。



图 2-1 基本绘图示例

下面对其中涉及到的类和函数进行详细说明,文本显示相关接口会在后面章节单独描述,这里不做说明:

2.1.1.1 Paint 类

1. setStrokeWidth(float width)。 设置边框的线宽。参数为宽度值,以像素为单位。对比效果图可以看出,线宽就是图中的直线或者矩形边框的宽度,以像素为单位。红色直线和矩形的宽度为6像素。而第二三条绿色直线的宽度为10像素。从图中也可以明显看出绿色直线比红色直线宽。

2.setColor(int color)。设置绘画对象的颜色。图中线条和矩形都颜色都由此函数指定。

参数颜色的格式为(16进制):0x (Alpha)ff (R)ff (G)ff(B)ff。参数可以用如下几种方式获得:

(1) Color 类提供的颜色常量。Android通过android.graphics.Color提供了一个Color应用类,定义了一些颜色常量和获得颜色的函数。如Color.WHITE 代表白色。如果我们想将画笔颜色设为白色,就可以这样调用:setColor(Color.WHITE);

(2) Color 类提供的静态函数:

Color.rgb(int r,int g,int b), 根据分量r,g,b的值指定颜色。请注意,这里r,g,b取值范围[0,255]。

Color.argb(inta,int r,int g,int b), 根据分量a,r,g,b的值指定颜色。这里a,r,g,b取值范围[0,255]。

3. setAlpha(int a)。设置绘画对象的透明度。等同于:

setColor((a<<24) & getColor())。a为透明度值,应取值为[0,255]。

4. setARGB(int a,int r,int g,int b)。设置绘画对象的颜色和透明度。等同于“

setColor((a<<24) & (r<<16) & (g<<8) & b)。a,r,g,b取值范围[0,255]。

5. setStyle(Paint.Style style)。设置填充的类型,目前参数取值为系统提供的三个枚举值,分别为:

Paint.Style.STROKE:只绘制边框。效果如第一个红色矩形框所示。边框线的宽度为setStrokeWidth指定的像素值。

Paint.Style.FILL:绘制实心区域。效果如第二个绿色实心矩形所示。矩形的宽和高有传入参数中的RectF对象决定。

Paint.Style.FILL_AND_STROKE:绘制边框和实心区域。效果如第三个绿色半透明实心区域所示。因此,此处的矩形宽度应该为RectF中设定的宽度+2*(setStrokeWidth指定的宽度)。细心的读者也可以从图上看出来,最后一个矩形要比第二个矩形大一点点。

2.1.1.2 Canvas 类

Canvas类提供了一系列基本图形的绘制接口,包括点,直线,圆,矩形,贝塞尔曲线等等。除此之外Canvas还提供了其他的相对复杂的功能,包括:画布的几何变换,裁剪,绘制位图,绘制文本等等。本章只介绍基本图形的绘制,其他内容会在后续部分逐步介绍。

首先介绍下画布的坐标系。以左上角为原点,横向为x方向,纵向为y方向,如下图所示:



所有函数调用的参数都是参照此坐标系设定的。

2.1.2 自定义画布绘制

自定义画布的绘图过程和2.1.1相同,不多做描述。不同之处在于,最后的结果不是绘制到系统提供的画布上,而是绘制到一张位图上。

这里主要给出如何创建画布的过程:

首先创建一张位图:

Bitmap
bitmap= Bitmap.createBitmap(480, 800, Bitmap.Config.ARGB_8888);
然后根据此位图创建画布:
Canvas canvas =newCanvas(bitmap);

即可在此画图上绘制了:

//在x,y坐标点出绘制点。

canvas.drawPoint(x,y,paint);

2.2 基本形状的绘制

这些基本的图形函数主要在Canvas类中定义,用户可以直接通过一个canvas对象调用这些函数绘制图形。

2.2.1 点

Canvas类中定义了三个画点的函数,分别是:

publicvoid drawPoint (float x, float y, Paint paint),在坐标点(x,y)处绘制点。点的颜色和大小有paint参数限定。

其中,Paint setColor 函数定义了点的颜色。setStrokeWidth(floatwidth) 函数定义了点的大小。此处请注意:drawPoint绘制的点其实是一个正方形。正方形的中心点在(x,y),而正方形的边长则是由setStrokeWidth的参数width确定。稍后的例子将会说明这一点。

publicvoid drawPoints (float[] pts, Paint paint),依次绘制有pts数组定义的多个点。其中,pts数组定义了多个点,每两个两个值分别代表一个点,依次为(x,y)。

publicvoid drawPoints (float[] pts, int offset, int count, Paint paint),功能同上。只是并不绘制pts数组中的所有点,而是绘制从offset开始,共计count个值,这里请注意,count是针对pts下标而言,数组中的两个数值才能定义一个点,因此,此处的count值应该为2的倍数。

2.2.2 直线

Canvas中绘制直线的接口也有三个,分别是:

drawLine(floatstartX, float startY, float stopX, float stopY, Paint paint),绘制一条起点为(startX,startY),终点为(stopX,stopY)的直线。直线的颜色,宽度,线型的特征有paint参数指定。

drawLines(float[]pts, Paint paint)。绘制多条线段。线段的端点在pts数组中定义。此处请注意:pts中定义的线段是不连续的。例如:pts数组共有12个成员,也就是描述了6个点。记为A,B,C,D,E,F,那么调用drawLines的结果得到的只是三条线段AB,CD和EF,而BC和DE之间是没有线段相连的。

drawLines(float[]pts, int offset, int count, Paint paint)。功能同上。只是并不绘制pts数组中的所有点,而是绘制从offset开始的共计count的数值定义的多条线段。注意,因为一条线段需要两个点才能确定,所以此处count值应该为4的倍数。

2.2.3 矩形

Canvas中绘制矩形的接口有四个,分别是:

drawRect(floatleft, float top, float right, float bottom, Paint paint)。绘制有left,top,right和bottom定义四条边的矩形。

drawRect(RectFrect, Paint paint)。绘制由rect定义的矩形。

drawRect(Rectrect, Paint paint)。绘制由rect定义的矩形。

drawRoundRect(RectFrect, float rx, float ry, Paint paint)。绘制圆角矩形。rx,ry定义弧度在x,y方向的半径。

2.2.4 曲线

drawArc(RectFoval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)。定义了一个以oval为外接矩形的椭圆。startAngle为开始角度,sweepAngle为圆弧的角度,这两个参数的单位都是角度,取值为[0,360]。userCenter为ture时,画出的不是一个弧形而是一个扇形。

publicvoid drawCircle (float cx, float cy, float radius, Paint paint) 定义了一个以(cx,cy)为圆心,radius为半径的圆。

drawOval(RectF oval, Paint paint) 定义了一个以oval为外接矩形的椭圆。

2.2.5 基本图形示例

运行效果如下图:



上代码:
public class LineArc extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(new SampleView(this));

}

private static class SampleView extends View {

private Paint mPaint;

public SampleView(Context context) {

super(context);

setFocusable(true);

mPaint = new Paint();

}

@Override protected void onDraw(Canvas canvas) {

canvas.drawColor(Color.WHITE);

drawPoints_1(canvas);

drawPoints_2(canvas);

drawLines_1(canvas);

drawLines_2(canvas);

drawArc_1(canvas);

drawArc_2(canvas);

}

protected void drawPoints_1(Canvas canvas) {

Paint paint = mPaint;

int startx = 100;

int starty = 100;

int pixwidth = 30;

paint.setColor(Color.BLUE);

paint.setStrokeWidth(pixwidth);

float[] Pts = new float[2];

Pts[0] = startx;

Pts[1] = startx;

canvas.drawPoints(Pts, paint);

paint.setColor(Color.RED);

RectF r = new RectF();

r.left = 2*startx;

r.top = starty - pixwidth/2;

r.right = r.left + pixwidth;

r.bottom = r.top + pixwidth;

paint.setStyle(Paint.Style.FILL);

canvas.drawRect(r, paint);

}

protected void drawPoints_2(Canvas canvas) {

Paint paint = mPaint;

int linecount = 8;

float[] Pts = new float[linecount];

Pts[0] = 100;

Pts[1] = 100;

Pts[2] = 300;

Pts[3] = 100;

Pts[4] = 100;

Pts[5] = 200;

Pts[6] = 300;

Pts[7] = 200;

paint.setColor(Color.BLUE);

paint.setStrokeWidth(30);

canvas.save();

canvas.translate(0, 100);

canvas.drawPoints(Pts, paint);

canvas.restore();

canvas.save();

canvas.translate(300, 100);

paint.setColor(Color.RED);

canvas.drawPoints(Pts,0,4,paint);

canvas.restore();

}

protected void drawLines_1(Canvas canvas) {

Paint paint = mPaint;

int linecount = 12;

float[] Pts = new float[linecount];

Pts[0] = 100;

Pts[1] = 100;

Pts[2] = 300;

Pts[3] = 100;

Pts[4] = 100;

Pts[5] = 200;

Pts[6] = 300;

Pts[7] = 200;

Pts[8] = 100;

Pts[9] = 100;

Pts[10] = 100;

Pts[11] = 200;

paint.setColor(Color.BLUE);

paint.setStrokeWidth(2);

canvas.save();

canvas.translate(0, 300);

canvas.drawLines(Pts, paint);

canvas.restore();

canvas.save();

canvas.translate(300, 300);

canvas.drawLines(Pts,0,8,paint);

canvas.restore();

}

protected void drawLines_2(Canvas canvas) {

Paint paint = mPaint;

paint.setColor(Color.BLUE);

paint.setStrokeWidth(10);

mPaint.setStyle(Paint.Style.STROKE);

paint.setStrokeCap(Paint.Cap.ROUND);

int startX = 100;

int startY = 0;

int endX = 500;

int endY = 0;

canvas.save();

canvas.translate(0, 600);

canvas.drawLine(startX,startY,endX,endY,paint);

canvas.restore();

startY +=30;

endY += 30;

canvas.save();

canvas.translate(0, 600);

Path path = new Path();

path.reset();

path.moveTo(startX,startY);

path.lineTo(endX, endY);

canvas.drawPath(path, paint);

canvas.restore();

}

protected void drawArc_1(Canvas canvas) {

Paint paint = mPaint;

paint.setColor(Color.BLUE);

paint.setStrokeWidth(10);

mPaint.setStyle(Paint.Style.STROKE);

int xstart = 30;

int ystart = 30;

int width = 300;

int height = 200;

RectF rect = new RectF();

rect.left = xstart;

rect.top = ystart;

rect.right = xstart + width;

rect.bottom = ystart + height;

canvas.save();

canvas.translate(0, 600);

canvas.drawArc(rect,0,180,true, paint);

canvas.restore();

canvas.save();

canvas.translate(350, 600);

paint.setColor(Color.RED);

canvas.drawArc(rect,0,180,false, paint);

canvas.restore();

}

protected void drawArc_2(Canvas canvas) {

Paint paint = mPaint;

paint.setColor(Color.BLUE);

paint.setStrokeWidth(10);

mPaint.setStyle(Paint.Style.STROKE);

int xstart = 30;

int ystart = 30;

int width = 300;

int height = 200;

RectF rect = new RectF();

rect.left = xstart;

rect.top = ystart;

rect.right = xstart + width;

rect.bottom = ystart + height;

canvas.save();

canvas.translate(0, 850);

canvas.drawOval(rect, paint);

canvas.restore();

canvas.save();

canvas.translate(350, 850);

paint.setColor(Color.RED);

canvas.drawCircle(100, 100, 80, paint);

canvas.restore();

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐