绘制基础,绘图基础

图片 1

Bitmap

资料来源:扔物线的技术分享
http://hencoder.com/

线上箭头表示画线的方向。WINDING模式和ALTERNATE模式都会填充三个封闭的L型区域,号码从1到3。两个更小的内部区域,号码为4和5,在ALTERNATE模式下不被填充。但是在WINDING模式下,号码5的区域会被填充,这是因为区域的内部到达图形的外部必须穿过两条相同方向的线。号码为4的区域不会被填充,因为射线必须穿越两条边框线,但是这两条边框线的绘制方向相反。

UI-1 Drawing

图片 2图片 3

自定义绘制技术点总结:

方式:重写绘制方法,其中最常用的是 onDraw()

关键: Canvas 的使用

  1, Canvas 的绘制类方法: drawXXX() (关键参数:Paint)

  2,Canvas 的辅助类方法:范围裁切(clipXXX())和几何变换

补充:使用不同的绘制方法来控制遮盖关系

  1 /*-------------------------------------------
  2 ALTWIND.C -- Alternate and Winding Fill Modes
  3              (c) Charles Petzold, 1998
  4 -------------------------------------------*/
  5 
  6 #include <Windows.h>
  7 
  8 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  9 
 10 int WINAPI WinMain( __in HINSTANCE hInstance
 11                     , __in_opt HINSTANCE hPrevInstance
 12                     , __in LPSTR lpCmdLine
 13                     , __in int nShowCmd )
 14 {
 15     static TCHAR szAppName[] = TEXT("AltWind");
 16     HWND hwnd;
 17     MSG msg;
 18     WNDCLASS wndclass;
 19 
 20     wndclass.style = CS_HREDRAW | CS_VREDRAW;
 21     wndclass.lpfnWndProc = WndProc;
 22     wndclass.cbClsExtra = 0;
 23     wndclass.cbWndExtra = 0;
 24     wndclass.hInstance = hInstance;
 25     wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 26     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
 27     wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
 28     wndclass.lpszMenuName = NULL;
 29     wndclass.lpszClassName = szAppName;
 30 
 31     if (!RegisterClass(&wndclass))
 32     {
 33         MessageBox(NULL, TEXT("Program requires Windows NT!")
 34             , szAppName, MB_ICONERROR);
 35         return 0;
 36     }
 37 
 38     hwnd= CreateWindow(szAppName, TEXT("Alternate and Winding Fill Modes")
 39         , WS_OVERLAPPEDWINDOW
 40         , CW_USEDEFAULT, CW_USEDEFAULT
 41         , CW_USEDEFAULT, CW_USEDEFAULT
 42         , NULL, NULL, hInstance, NULL);
 43 
 44     ShowWindow(hwnd, nShowCmd);
 45     UpdateWindow(hwnd);
 46 
 47     while (GetMessage(&msg, NULL, 0, 0))
 48     {
 49         TranslateMessage(&msg);
 50         DispatchMessage(&msg);
 51     }
 52 
 53     return msg.wParam;
 54 }
 55 
 56 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 57 {
 58     static POINT aptFigure[10] = {10, 70
 59                                 , 50, 70
 60                                 , 50, 10
 61                                 , 90, 10
 62                                 , 90, 50
 63                                 , 30, 50
 64                                 , 30, 90
 65                                 , 70, 90
 66                                 , 70, 30
 67                                 , 10, 30};
 68     static int cxClient, cyClient;
 69     HDC hdc;
 70     int i;
 71     PAINTSTRUCT ps;
 72     POINT apt[10];
 73 
 74     switch (message)
 75     {
 76     case WM_SIZE:
 77         cxClient = LOWORD(lParam);
 78         cyClient = HIWORD(lParam);
 79         return 0;
 80 
 81     case WM_PAINT:
 82         hdc = BeginPaint(hwnd, &ps);
 83         SelectObject(hdc, GetStockObject(GRAY_BRUSH));
 84 
 85         for (i = 0; i !=10; ++i)
 86         {
 87             apt[i].x = cxClient * aptFigure[i].x / 200;
 88             apt[i].y = cyClient * aptFigure[i].y / 100;
 89         }
 90         SetPolyFillMode(hdc, ALTERNATE);
 91         Polygon(hdc, apt, 10);
 92 
 93         for (i = 0; i != 10; ++i)
 94         {
 95             apt[i].x += cxClient / 2;
 96         }
 97         SetPolyFillMode(hdc, WINDING);
 98         Polygon(hdc, apt, 10);
 99 
100         EndPaint(hwnd, &ps);
101         return 0;
102 
103     case WM_DESTROY:
104         PostQuitMessage(0);
105         return 0;
106     }
107 
108     return DefWindowProc(hwnd, message, wParam, lParam);
109 }

学习过程:

1,Canvas 的 drawXXX() 系列方法及Paint最常见的使用;

2,Paint的进阶攻略;

3,Canvas对绘制的辅助——范围裁切和几何变换;

4,使用不同的绘制方法来控制绘制顺序;


ALTWIND.C

丨一切的开始:onDraw()

    别漏写了super.onDraw()。

图形的坐标(按一个100*100单位的区域设定)存储在aptFigure数组中。这些坐标会根据客户去的宽度和高度按比例缩放。程序显示两个图形,一个使用ALTERNATE填充模式,另一个使用WINDING填充模式。结果如图:

丨Canvas.drawXXX() 和 Paint 基础

    Paint.setStyle(Style
style)设置绘制模式():Paint.style.FILL、STROKE、FILL_AND_STROKE

    Paint.setColor(int color)设置颜色

    Paint.setStrokeWidth(float width)设置线条宽度

    Paint.setTextSize(float textSize)设置文字大小

    Paint.setAntiAlias(boolean aa)设置抗锯齿开关      
 可以在创建时Paint paint=new Paint(Paint.ANTI_ALIAS_FLAG);


图片 4

Canvas.drawColor()、Canvas.drawRGB()、Canvas.drawARGB():

作用整个绘制区域,用于绘制前期设置背景底色或绘制后期设置蒙板;


drawCircle(float centerX, float centerY, float radius, Paint paint):

xy设置圆心,以view的左顶点为坐标系原点,radius设置半径;

注意:Paint能做的优先交给Paint去做,drawXXX方法参数尽量只包含特有的属性
如圆心半径;


drawRect(float left, float top, float right, float bottom, Paint paint) 

left,top,right,bottom是矩形四条边相对于xyxy轴的坐标;

两个重载方法drawRect(RectF rect, Paint paint)和drawRect(Rect rect, Paint
paint),可以直接填写RectF或Rect对象来绘制矩形;


drawPoint(float x, float y, Paint paint)

点的大小可以通过paint.setStrokeWidth(width)来设置;

点的形状可以通过paint.setStrokeCap(cap)来设置,端点有圆头 (ROUND)、平头
(BUTT) 和方头 (SQUARE) 三种;

FILL模式下的drawCircle()和drawRect()也能达到相同效果,按偏好选择;


drawPoints(float[] pts, Paint paint) 批量画点

drawPoints(float[] pts, int offset, int count, Paint paint) 

float[] points={0,0,50,50,50,100,100,50,100,100,150,50,150,100};//
绘制四个点:(50, 50) (50, 100) (100, 50) (100, 100)

canvas.drawPoints(points,2/* 跳过两个数,即前两个 0 */,8/* 一共绘制 8
个数(4 个点)*/, paint);


发表评论

电子邮件地址不会被公开。 必填项已用*标注