你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【安富莱STemWin教程】第26章 抗锯齿基础介绍

[复制链接]
baiyongbin2009 发布时间:2015-2-6 16:54
特别说明:完整STemWin的1-60期教程和配套实例下载地址:链接
3 q9 q# h4 N0 w" k3 \  k* q. @
第26章      抗锯齿基础介绍
9 I( n  ~- ]0 v8 P0 d8 y
    本期教程主要是跟大家讲解一下抗锯齿,关于抗锯齿,在第16章讲解字体显示的时候也讲了点。本期教程就是跟大家详细的讲解一下抗锯齿方面的知识。
     线条由一系列必须位于显示坐标处的像素近似构成。因此,可能看起来呈锯齿状,尤其是近似水平线或近似垂直线。这种现象称为锯齿(aliasing)。抗锯齿是对线条和曲线进行平滑处理。可以减少不完全水平或垂直的线条的楼梯状锯齿。STemWin支持不同的抗锯齿质量、无锯齿字体和高分辨率坐标。
    26. 1  介绍
    26. 2 抗锯齿API函数实例演示
    26. 3 总结
26.1  介绍
    抗锯齿通过使背景色与前景色相“混合”的方法来平滑曲线和对角线。背景色与前景色之间使用的阴影越多,抗锯齿效果越好 (计算时间越长)。
26.1.1      抗锯齿质量
    抗锯齿处理的质量由GUI_AA_SetFactor()函数设定,通过下面的截图给大家介绍一下抗锯齿因子与对应结果之间的关系。
26.1.png
# I/ x5 J8 y; L0 `) @
    第一条线未经抗锯齿处理(因子1)。第二条线以因子2进行了抗锯齿处理。也就是说,从前景到背景的阴影数为2 x 2 = 4。下一条线以抗锯齿因子3绘制,因而有3 x 3 = 9个阴影,如此等等,不一而足。因子4足以处理多数应用。进一步增加抗锯齿因素不会大幅改善结果,但会增加计算时间。
26.1.2      抗锯齿字体
    在前面第16章介绍字体的时候讲解过2bpp和4bpp字体显示效果,下面再给大家展示下不使用抗锯齿和使用两种抗锯齿下字母C的显示效果:
& l3 l. v  {0 S" {+ w
    26.2.png
    无锯齿字体可以通过STemWin字体转换器创建。使用无锯齿字体的一般目的是改进文字的外观。虽然高质量抗锯齿比低质量搞锯齿处理看起来更好美观,但计算时间和存储器占用量也会相应增加。低质量(2bpp)字体需要两倍于无抗锯齿处理(1bpp)字体的存储器容量;高质量(4bpp)字体则需要四倍的存储器容量。
26.1.3      高分辨率坐标
    在使用抗锯齿法绘制项目时,使用的是与常规 (无抗锯齿处理)绘图程序相同的坐标。这是默认模式。在函数参数中无需考虑抗锯齿因子。例如,要从(50, 100)到(100, 50)绘制一条抗锯齿线条,则需写入以下代码:
       GUI_AA_DrawLine(50, 100, 100, 50);
    借助STemWin的高分辨率功能,大家可以使用取决于抗锯齿因子和显示尺寸的虚拟空间。使用高分辨率坐标的优势在于,项目不但可以置于显示器的物理位置上,而且可以置于物理位置之间。
    下图展示的是一个高分辨率像素的虚拟空间,其抗锯齿因素为3:
26.3.png
6 n4 l# g  V9 C( g: @
     以抗锯齿因子3,从像素(50,100)到像素(100, 50)绘制一条高分辨率线条,则需写入以下代码:
        GUI_AA_DrawLine(150, 300, 300, 150);
     高分辨率坐标必须通过GUI_AA_EnableHiRes()程序启用,并用GUI_AA_DisableHiRes()禁用。
26.2  抗锯齿API函数实例演示
    STemWin支持的抗锯齿函数主要如下:
26.4.png

, n2 L$ W! b8 l. U% u26.2.1      函数GUI_AA_DrawArc
模拟器上运行代码如下:
  1. #include "GUI.h"
    4 x7 W: N0 L2 A

  2. : D: z4 d* w- d. S
  3. void MainTask(void)  i& r; `1 q, @! ]' {1 V
  4. {: \3 G" r5 X1 @; }' w
  5.      GUI_Init();
    : A; F/ _2 I% Z, Z! V
  6.   H) o! z: o; z( v. |: K& S% S# `
  7.      /* 设置画笔粗细 */4 I, q7 J2 F9 I. G
  8.      GUI_SetPenSize(4);# x' S  o$ W- b  E1 l
  9.      GUI_SetColor(GUI_RED);* A# {. B% j3 H% O) k0 u6 w
  10.    
    # y# p: m- G) ~* P. L0 `, e
  11.      /* 使能高分辨率 */
    ; c( }5 X, |4 A& ^. i
  12.      GUI_AA_EnableHiRes();& B& ^% v8 \8 t* [1 s) H! Z

  13. 6 U: @; l6 a9 W* K
  14.      /* 抗锯齿因数选择1 */& r7 K0 B" L, F
  15.      GUI_AA_SetFactor(1);
    % [+ V, q  W5 {4 ^
  16.      GUI_AA_DrawArc(50,120,50,50,0,180);+ g' P3 b/ }/ A/ R4 K9 c

  17. ; b8 y; B$ l  A% J
  18.      /* 抗锯齿因数选择3 */1 Q# ]( P$ n9 e: ?4 @
  19.      GUI_AA_SetFactor(3);. Q1 O! P+ H% U( I. i
  20.      GUI_AA_DrawArc(160*3,120*3,50*3,50*3,0,180);
    9 Y* M5 \" B3 h

  21. 0 Z  B4 ?4 H) s4 C
  22.      /* 抗锯齿因数选择3 */
    5 ^+ F2 e* L0 e# F6 h
  23.      GUI_AA_SetFactor(6);
    # \- }/ r8 |1 J$ A+ b% l; l( O! T
  24.      GUI_AA_DrawArc(270*6,120*6,50*6,50*6,0,180);- ?7 m/ ~1 ?6 m" N
  25.     / j% B  x7 j9 t1 ?; B- e; M. d
  26.      while(1)5 I1 P! ]( d& [5 b; @2 |9 Q
  27.      {7 V5 Y+ C1 l1 G* h! [
  28.          GUI_Delay(100);
    ) y$ ^% z7 q3 Z
  29.      }$ J7 _/ V. U2 i1 g
  30. }
复制代码
     要注意选择了抗锯齿因数后,绘制是得乘以相应的因数。
显示效果如下:
26.5.png
7 N' `5 {! y* e* ]! V/ w( k! Y
26.2.2      函数GUI_AA_DrawLine
    模拟器上运行程序如下:
  1. #include "GUI.h"" h% k. O, ]1 ]2 u# ]* U4 A
  2. 0 k% h( e. |" Z3 C3 \
  3. void MainTask(void)
    5 C9 I) r( T  J' A
  4. {
    8 y0 M6 L0 m8 _6 Q9 t: H
  5.      GUI_Init();! C+ r! |1 O: n0 n9 r7 R- E8 ?

  6. % C8 P# S# M# S$ {# u3 D& z! @+ Y& i
  7.      /* 设置画笔粗细 */' [" @" f! _" y
  8.      GUI_SetPenSize(40);
    1 N# k$ {! ~3 c0 T" f
  9.      GUI_SetColor(GUI_RED);+ H! c- F6 x4 y
  10.     & t2 w- d3 ?) |) Z- z& \. ^% c
  11.      /* 使能高分辨率 */
    + O* o, l9 i9 C0 H/ \
  12.      GUI_AA_EnableHiRes();
    ) A2 G4 K$ |$ H, @% Z
  13. 5 Y# B5 `+ P; V% y. Z
  14.      /* 抗锯齿因数选择1 */
    & o8 n, f, u6 O7 p: K! r7 Z! T
  15.      GUI_AA_SetFactor(1);9 g! [+ N/ I/ `  k; @. {
  16.      GUI_AA_DrawLine(50,40,50,120);
    9 M4 E, o8 W6 m: ?- S
  17. 5 j* A( W7 z8 M
  18.      /* 抗锯齿因数选择3 */
    & k4 |1 H! C$ Z/ K8 B
  19.      GUI_AA_SetFactor(3);; [8 D( G/ C. d9 d
  20.      GUI_AA_DrawLine(150*3,40*3,150*3,120*3);
    0 L0 I) k5 d5 R8 @* \
  21. * \/ }; G- v% N2 r8 W; g, p1 S" Q
  22.      /* 抗锯齿因数选择3 */7 {, S% V" h# c5 e- ?) a
  23.      GUI_AA_SetFactor(6);
    6 n, j7 @* `) Q) S8 Q9 n' U
  24.      GUI_AA_DrawLine(250*6,40*6,250*6,120*6);" P4 x3 c' F; n1 w! Z  J. Z
  25.     2 ~! e' v6 b$ w
  26.      while(1)! d6 ?* B0 d3 K' k" I9 T
  27.      {% k* ]1 F4 s* L  w# S
  28.          GUI_Delay(100);
    * n8 F: m& `% t3 f
  29.      }, R" {: B. R+ h
  30. }
复制代码
实际效果如下:
26.6.png
' E5 Y( \) W2 q  @$ b; I
26.2.3      函数GUI_AA_DrawPolyOutline
    模拟器上运行代码如下:
  1. #define countof(Array) (sizeof(Array) / sizeof(Array[0]))
    " v2 A9 q1 C8 R8 b: N

  2. ! E* \) s: z1 p
  3. static GUI_POINT aPoints[] = {! B7 b  P! L! F% E$ U9 k. Y7 [) e
  4.      { 0, 0 },6 m6 m) C& g. }  H& n: O, t& `
  5.      { 15, 30 },' v1 M6 M: P- l5 W' K" [$ z7 v
  6.      { 0, 20 },7 _& R" ]) u. z0 X8 C0 b( \
  7.      {-15, 30 }" _+ f8 n+ M. S1 J; H0 e$ V# |) e
  8. };. F4 d5 I: l; l  O: D( Z2 V* R' [

  9. + v% f7 V& C+ e  [1 i+ f- n
  10. void MainTask(void)- r, l; |4 Z! F8 @. F  ?
  11. {
    ) r7 r! F2 E; z. L
  12.      GUI_Init();5 m8 _9 J. x, g& z; K
  13. & `& E0 [# b. H- O7 a1 N  ~( }
  14.      GUI_SetPenSize(10);: f6 F/ u; R0 e2 }! |
  15.      GUI_SetColor(GUI_RED);
    - {# Q  g! [- q' A3 n

  16. 5 [1 ^8 m% x  I: u# z& v
  17.      GUI_AA_DrawPolyOutline(aPoints, countof(aPoints), 3, 150, 40);
    ! d) l; {% l5 d2 j/ U4 z% A: [
  18.     , V; _- r7 Z; W6 M4 h' `
  19.      while(1)
    : y) N. E1 A$ w! H4 B% x
  20.      {% @/ l: ~& J- t- x4 f
  21.          GUI_Delay(100);2 k$ r$ i+ o) d7 O7 H# a% V
  22.      }8 S& H* S- B0 O$ q  P2 ]; V2 i
  23. }
复制代码
    使用这个函数要注意:通过连接终点和起点,可使绘制的多线条自动闭合。起点不得再次指定为终点。
    如果采用高分辨率模式,则必须使用高分辨率坐标。否则,必须指定为像素值。默认情况下,该函数处理的定义点不超过10个。如果多边形由10个以的点构成,则必须使用GUI_AA_DrawPolyOutlineEx()函数。
实际效果如下:
26.7.png

+ F4 ~: B1 j$ T+ z26.2.4      函数GUI_AA_DrawRoundedRect
    模拟器上运行的代码如下:
  1. #include "GUI.h"
    5 B8 s& X# w3 M! F" Y# O! M  H

  2. 8 G2 }; ~* W: q
  3. void MainTask(void)
    , f3 D* T+ k6 h; ]; J4 x# g
  4. {8 L6 [2 ~8 ~" p& T; Z2 w6 T2 S
  5.      GUI_Init();) v$ r; ~6 F) u& g! m  K* H' ^% G
  6.      GUI_SetBkColor(GUI_WHITE);
    * V$ t7 F  v$ Q4 f) k# s8 ]
  7.      GUI_Clear();
    & I  V8 s* F0 ]; z- L& n" U
  8.      GUI_SetColor(GUI_DARKBLUE);
    - G) \0 m. ~0 k8 ?- y9 I5 L1 q
  9.      GUI_SetPenSize(5);
    ) [3 p/ M' i! p0 `
  10.      GUI_AA_DrawRoundedRect(10, 10, 50, 50, 5);* n6 F0 V8 i8 D' t/ Q) {
  11.    
    " Q( G7 O# v  f3 R  s- A
  12.      while(1), A4 r$ z# {3 b; w" q/ [: v
  13.      {2 }" X* l4 q8 V1 Q$ [
  14.          GUI_Delay(100);+ i  o! Q3 i/ c$ S6 z6 W1 Z6 j
  15.      }
    7 c* H- {2 c- J
  16. }
复制代码
实际显示效果如下:
26.8.png
26.2.5      函数GUI_AA_FillCircle
    模拟器上运行的代码如下:
  1. #include "GUI.h"
    2 N5 K! O7 r5 o' U
  2. + d, {$ ~# ^- B$ E$ q& L
  3. void MainTask(void)) l% M& R0 k& Z; ^8 v
  4. {
    ) i% @: l2 S% `/ m. g, T5 U
  5.      GUI_Init();
    ( a6 _. N' Y: ]* i+ a1 T
  6.      GUI_AA_EnableHiRes();
    ) [% R" w( q  X7 w$ ^% D* i: K6 Q
  7.      GUI_SetBkColor(GUI_WHITE);2 X5 V! I0 O' D- v, }
  8.      GUI_Clear();
    0 ~9 \) l2 |/ @% u$ e8 j: J4 {1 i
  9.      GUI_SetColor(GUI_DARKBLUE);9 O) t0 g8 I/ Z' \! V  D
  10.      GUI_SetPenSize(5);
    $ k0 |+ y' j" Q9 s2 w* p
  11.      GUI_AA_SetFactor(3);
    ( ~, L; g1 _3 Q+ F- B& Q
  12.      GUI_AA_FillCircle(160*3, 120*3, 80*3);
    . T8 A8 c! s) o7 y* I: I
  13.    
    9 w5 [! T. g7 w* h
  14.      while(1)' ^) v- z* @, w3 G6 P6 g
  15.      {
    " t8 f8 Z  t) F+ E& r3 l
  16.          GUI_Delay(100);/ T4 B+ D1 Y8 Y2 k; P1 `0 M
  17.      }7 W6 I2 V# |( f1 e7 o& W7 C* L
  18. }
复制代码
实际显示效果如下:
26.9.png
26.2.6      函数GUI_AA_FillPolygon
    模拟器上运行的代码如下:
  1. #include "GUI.h"1 {6 V! c' \7 x7 N% z& m3 c
  2. 8 f. u0 R" Y  @' k2 z+ Z
  3. #define countof(Array) (sizeof(Array) / sizeof(Array[0]))
    / W2 W8 p5 o' s; ^
  4. + V- q( O* Z( c6 z; p% F
  5. static GUI_POINT aPoints[] = {   (1)
    ; O2 Q7 S1 }* |) o- Z
  6.      { 0, 0 },& [$ I& |6 j1 k" P& e) w
  7.      { 70, -30 },: ^8 p- Z- P' K# I+ F' j
  8.      { 0, 50 },
    ( t6 X: c2 @. S* V6 |" J4 |
  9.      {-70, -30 }
    " U: w- {) \3 _
  10. };' W; F& E" g$ J" T$ u2 z% Q: F
  11. + R: s1 m( O- v7 s
  12. void MainTask(void): f" L% }, ^& d. }% Y
  13. {
    & W$ F: ^/ w& T" J! r
  14.      GUI_Init();$ U, _" i6 j( D: A& v& E

  15. & B" r' y" J" ]& N$ {- J' v
  16.      GUI_SetPenSize(10);1 u7 }! R2 C/ Z2 [7 l
  17.      GUI_SetColor(GUI_RED);
    $ R" C/ \& Y# j- k9 f$ Z3 W0 @8 D

  18. " {0 `7 L- E5 Y5 h. I3 S4 b* j+ ^
  19.      GUI_AA_FillPolygon(aPoints, countof(aPoints), 150, 40);
    / [! }9 U2 }% M/ P3 e
  20.    
    * \8 g$ }) `5 {2 p
  21.      while(1)
    $ l* Q% q! f  ?( z% h* \# h! Q% {
  22.      {
    - n/ z5 |5 q9 o! S6 M/ |
  23.          GUI_Delay(100);
    & m& P& @& f! Q0 ]
  24.      }4 Z' k6 J) G7 T, J
  25. }
复制代码
1.    这些坐标点是相对于函数GUI_AA_FillPolygon中的X,Y坐标而言的。
实际运行效果如下:
26.10.png
9 q& Q2 t; ?# H( s( {& w) V
26.2.7      函数GUI_AA_FillRoundedRect
    模拟器上运行的代码如下:
  1. #include "GUI.h"
    % t9 }% g, L3 X$ `( G8 Z! s
  2. # P5 ^, T3 j/ C4 x# D% b4 N) C7 ]
  3. void MainTask(void) {
    ( f5 Q; T; Y" t& ?" {# d- p& a  a
  4.      GUI_Init();* [3 f* U' u% c/ t" s. P
  5.      GUI_SetBkColor(GUI_WHITE);, g# Q9 y: J& l
  6.      GUI_Clear();  r( P) ]  G% U: _0 P7 h" [
  7.      GUI_SetColor(GUI_DARKBLUE);" Y) D! \8 |& _! w
  8.      GUI_AA_FillRoundedRect(10, 10, 54, 54, 5);
    0 S# X) ?; D; R# V
  9.      while (1);
    9 g' F6 a( z+ ^6 M) v8 w% \
  10.      {" X# F/ c: P3 N0 \" Z1 ^( F
  11.      }! u1 y3 {, b$ R
  12. }
复制代码
实际显示效果如下:
26.11.png

9 G0 O1 ^) p4 ]( F% {/ n  X
26.3  总结
    本期教程就跟大家讲这么多,下期教程再跟大家详细的讲解两个抗锯齿相关的应用例子。

' s/ _: t" _; x& C5 l- A
赞 收藏 评论3 发布时间:2015-2-6 16:54

举报

3个回答
feel-376797 回答时间:2015-2-8 18:56:31
谢谢分享
abb200628 回答时间:2015-2-11 18:39:34
很好的资料,谢谢分享
MouseCat 回答时间:2015-2-11 21:05:10
好东西,收藏了哈
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版