Bitmap
资料来源:扔物线的技术分享 http://hencoder.com/
线上箭头表示画线的方向。WINDING模式和ALTERNATE模式都会填充三个封闭的L型区域,号码从1到3。两个更小的内部区域,号码为4和5,在ALTERNATE模式下不被填充。但是在WINDING模式下,号码5的区域会被填充,这是因为区域的内部到达图形的外部必须穿过两条相同方向的线。号码为4的区域不会被填充,因为射线必须穿越两条边框线,但是这两条边框线的绘制方向相反。
UI-1 Drawing
自定义绘制技术点总结:
方式:重写绘制方法,其中最常用的是 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);
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);
本文由澳门新葡亰1495app发布于网络技术,转载请注明出处:第五章 绘图基础(ALTWIND)