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

[原创] 【安富莱STemWin教程】第9章 2-D图形库之绘制流...

[复制链接]
baiyongbin2009 发布时间:2015-1-13 16:43
本帖最后由 baiyongbin2009 于 2015-1-13 16:45 编辑
% ^9 i4 k0 m! k3 C, v+ O4 _! I; e
9 x% s' i  k7 K8 d/ c& p9 b特别说明:完整STemWin的1-60期教程和配套实例下载地址:链接
第9章      2-D图形库之绘制流位图
' g/ ]' H% ?* G7 e
    本期主要讲解2-D图形库的绘制流位图,与C文件格式的位图相反,流位图可放在任何位置。位图流可用于创建位图。这些位图可按与C文件格式位图相同的方式使用。此外,emWin支持直接绘制基于调色板的位图流,而不必在可寻址区域(RAM或ROM)放置完整的图像。
    9. 1  生成C流文件
    9. 2  开发板上实现流位图
    9. 3  实验总结
9.1  生成C流文件
    C流文件由与C文件相同的信息组成。它与C文件相反,数据流可位于任何地方,无需编译或与项目链接。C文件支持的所有输出格式对C流文件也可用。emWin支持从数据流创建位图并直接绘制数据流。
    这里顺便说一下压缩位图,这个可看可不看,位图转换器和emWin支持在生成的源代码文件中对位图进行游程编码(RLE)压缩。如果位图包含许多水平序列的等着色像素,则RLE压缩方法最有效。高效压缩的位图将节省大量的空间。但是,不建议对摄影图像进行压缩,因为它们通常不具有相同像素的序列。也应注意,压缩图像的显示时间会稍微更长。如果要保存使用RLE压缩的位图,可在另存为C文件时,选择一种压缩输出格式:“带调色板的C,压缩”或 “不带调色板的C,压缩”。显示压缩位图无需特殊功能;与显示不压缩位图的方法相同。
    获得的压缩比将随所用位图的不同而不同。图像水平均匀性越好,压缩比越高。每个像素的位数越高,产生压缩比也越高。下面我们以下面的图片为例子生成C流文件。
    下面我们以下面的图片为例子生成C流文件。
9.1.png
' ?) P6 `$ r' c1 i- f+ J
l 第一步:打开BmpCvt.exe(位置和前面讲的GUIBulder在一个文件夹),并载入图片
9.2.jpg

' ]$ {! V4 M3 K/ r( G. Q
l 第二步:做一下格式转换
9.3.jpg

) R/ l; k$ g; P2 R' h1 }' R
l 第三步:另存为C流文件即可,不过另存的时候要注意
9.4.png

% D8 P* p1 {2 Q2 o. [1 N. p
l 第四步:还有一些其它的格式,大家可以尝试一下,这里我只选择第一个作为实验。
9.5.png
5 `# T* ]8 o0 f# [
l 第五步:然后得到如下的文件,将其放到SD卡根目录下即可
9.6.jpg

, i6 o' Z8 F7 S! Q" b% r
9.2  开发板上实现流位图
    下面是流位图当前支持的格式:
9.7.png

4 h) ^) I& w6 A0 Y  c3 T
    GUI_CreateBitmapFromStream()这个函数支持任意格式的流位图创建,可以直接的创建咱们上面生成的流位图,如果知道流位图的格式,那么可以直接的调用特定的函数,当前支持的函数如下:
9.8.png
* n7 j  r$ m6 a$ J$ d; _
    这个东西该怎么的理解呢,这里举一个例子,咱们上面生成的那个C流文件是转换成了565格式,这里我们就可以使用函数GUI_CreateBitmapFromStream(),这个函数不管你转换成什么格式了,都可以创建的,还有一个就是GUI_CreateBitmapFromStream565(), 这个就是特定格式的转换,正好用在咱们上面转换好的C流文件。
    现在如何实现刚才那个C流文件的显示呢,我这里用三种方法显示咱们刚才生成的C流文件。
l  第一步:通过申请动态内存将C流文件加载到外部SRAM, 这里我们用的是外部2MB的SRAM做的动态内存,方法如下:
  1.          /* 申请一块内存空间 并且将其清零 */8 ]* z. a" ^4 o$ I6 {# z
  2. hMem = GUI_ALLOC_AllocZero(1024*512);) G5 |7 ?+ q* x3 ]7 S& D
  3.   Z0 F3 G6 M& f4 }; R; t
  4.      /* 将申请到内存的句柄转换成指针类型 */
    3 y" m3 {) y; ?- V3 n
  5.      _acBuffer2 = GUI_ALLOC_h2p(hMem);
    1 r" G" |! i9 A9 b* \2 ]
  6.     % y! S7 j& Q+ J& J
  7.      /* 打开文件 */        
    # ~4 P# B4 W+ @2 r
  8.      result = f_open(&file, sFilename, FA_OPEN_EXISTING | FA_READ | FA_OPEN_ALWAYS);+ \! g, V: y! P0 e
  9.      if (result != FR_OK)6 {5 v/ T! o& J7 A0 }% C
  10.      {! S0 A( k: t  v. |0 a' f3 Q+ g
  11.          return;9 p% I* R( q; X1 p. O& v
  12.      }) S; {* \$ A7 o: y( r6 T
  13. 4 J- n# m# d: I' Z0 n0 m
  14.      result = f_read(&file, _acBuffer2, file.fsize, &bw);; S- w% T" |/ K
  15.      if (result != FR_OK)' z2 L& h2 _) g! Q! m5 r6 r
  16.      {& h: o( s# L* Q5 V; P3 Z6 X! K; i8 c
  17.          return;
    ! B" {+ M; J! K# V- r: r/ S. P
  18.      }
复制代码
l  第二步:显示刚才加载到RAM中的数据。
    RAM中数据的加载有三种方法,分别如下:
方法一:直接调用函数 GUI_DrawStreamedBitmapAuto(_acBuffer2, 0, 0); 可以显示
方法二:GUI_CreateBitmapFromStream(&Bitmap,&Palette, _acBuffer2);
                GUI_DrawBitmap(&Bitmap, 0, 0);
方法三:GUI_CreateBitmapFromStream565(&Bitmap,&Palette, _acBuffer2);
                GUI_DrawBitmap(&Bitmap, 0, 0);
        实际运行代码如下:
  1. #include "includes.h"; X5 O! s: V' v% w' u) K
  2. #include "MainTask.h"
    " F! `) E0 M( Y- s+ y% F6 i  z

  3. + c3 g/ w* k2 S7 D! {
  4. + A# a( A/ V" X& A. T* d: h& ^
  5. #define Method3  /* 用于选择使用的显示方法 */
    9 e( {# G- l2 v) a9 F8 \; e
  6. ( @4 \( l* U& }+ W0 o2 V
  7. /*
    : W( ]/ [$ m4 H/ W: N' m0 n$ O
  8. *********************************************************************************************************0 \3 s' S8 F4 l( F
  9. *    函 数 名: _ShowStreamBitmap
    1 X& x  f+ Q# S) ^
  10. *    功能说明: 显示流位图
    3 U. e. k6 O% L  r
  11. *    形    参:sFilename  要读取的文件名
    / ]( ?7 r0 j( S$ J5 ]
  12. *    返 回 值: 无. C  m4 R( o+ j2 t
  13. *********************************************************************************************************
    ) \5 R, C3 Z( M; |7 m
  14. */; t4 E. ^0 [# n1 f& y
  15. static void _ShowStreamBitmap(const char * sFilename), L6 b: V( _# A9 |
  16. {' o. x4 E, d$ ?; F( k
  17.      GUI_HMEM hMem;
    " v* p  y( y* m; m7 G5 M5 _
  18.      char *_acBuffer2;
    4 q+ H/ a# O# w
  19.      BUTTON_Handle hButton;" P4 ~0 F; {' k4 g; H
  20. GUI_BITMAP Bitmap;
    2 g5 u% @7 \9 e/ V$ k
  21.     GUI_LOGPALETTE Palette;
    $ Z4 C. H# t2 N. e. ]) Y4 r; f0 l

  22. 9 {7 ?$ D5 _3 G& @$ t8 p
  23.     /* 创建一个按钮 */
    ' Z2 H, p* w) _. L4 r5 z$ C
  24.     hButton = BUTTON_Create(200, 200, 300, 200, GUI_ID_OK, WM_CF_SHOW);! _) E; R- G/ W4 Z2 P
  25.      /* 申请一块内存空间 并且将其清零    */
    ( Z1 R5 o0 P2 T  Z; p/ s2 B
  26.     hMem = GUI_ALLOC_AllocZero(1024*512);$ ~8 s0 z7 p7 c% u! ^7 V6 z4 U* r
  27.      /* 将申请到内存的句柄转换成指针类型 */3 x" }, h, Y+ F. ?
  28.      _acBuffer2 = GUI_ALLOC_h2p(hMem);2 z( J- ?+ F8 q) L5 m% v/ b. \
  29.    
    ) e" \( a& K# p! ~3 |; {9 Z
  30.      /* 打开文件 */        
    / Q1 p" G- l2 j7 a) A- S
  31.      result = f_open(&file, sFilename, FA_OPEN_EXISTING | FA_READ | FA_OPEN_ALWAYS);) o) U' `$ w7 N! e
  32.      if (result != FR_OK)+ n; q! B2 Z/ d4 R; x# b" z
  33.      {
    % E) @# v+ M5 o3 G  L8 I
  34.          return;
    & H( v  G/ ~( E) Y5 _' b8 w# M
  35.      }  p7 `( |9 @- `0 D* W
  36. ' V- c+ }" e8 E5 G. [; J7 j0 m1 v
  37.      /* 读取文件到动态内存 */
    # ?7 D2 S4 W' i4 R/ `5 T
  38.      result = f_read(&file, _acBuffer2, file.fsize, &bw);7 [7 {; Z' f. k( V3 j4 a
  39.      if (result != FR_OK)  g* o$ R8 \5 d9 Z+ [
  40.      {
    # p# h' h% W* i6 ^9 r
  41.          return;
    * H% [/ _# r- A
  42.      }
    2 \/ z" L" F( H3 m8 m1 F6 e

  43. ' |% {& E) Q0 g& D$ d
  44.      /* 显示方法一 */$ ]1 b* L+ _& u5 T/ z6 k
  45. #if defined Method1
    0 s: E" f1 m: A5 [+ B8 C
  46.      GUI_DrawStreamedBitmapAuto(_acBuffer2, 15, 15);3 j) a- e* c  @5 K0 S
  47.     + N. f& s( h4 x$ K
  48.      /* 显示方法二 */
    - ^1 @5 }1 K& t! \, r8 G. {
  49. #elif defined Method2 " j6 d+ ?* J/ _
  50.     GUI_CreateBitmapFromStream(&Bitmap, &Palette, _acBuffer2);
    8 y7 k" l1 s  V1 G" A; w7 K
  51.      GUI_DrawBitmap(&Bitmap, 15, 15);
    8 t: f3 s. _  P* a: t+ U; Y
  52.     9 `+ h9 |8 T6 ]) T. Z$ e+ U
  53.      /* 显示方法三 */7 a2 K5 Q' l6 {  Y. G
  54. #elif defined Method3 # x2 }% J7 f' P& v
  55.      GUI_CreateBitmapFromStream565(&Bitmap, &Palette, _acBuffer2);
    , ]% h; o% s' ^( i& W
  56.      GUI_DrawBitmap(&Bitmap, 15, 15);
    2 g) P" A3 I" ]: |( Z6 e
  57. #endif
    : B4 ~1 s, C4 i7 R

  58. 2 @6 \  G$ E! ]0 k
  59.      /* 下面几个函数没有调试出来,留作以后调试 */* q" N9 @! w, J9 A$ ]) X$ V
  60. //   BUTTON_SetStreamedBitmap(hButton, BUTTON_CI_UNPRESSED, (const GUI_BITMAP_STREAM *)&Bitmap);; T" z- i& Y0 O0 \9 u# `
  61. //  BUTTON_SetBitmap(hButton, BUTTON_BI_UNPRESSED, &Bitmap);
    * U" o! E4 R+ s- g- Z' K
  62. //   BUTTON_SetStreamedBitmapEx(hButton, BUTTON_BI_UNPRESSED, (const GUI_BITMAP_STREAM *)&Bitmap,0,0);" ~9 D' |; l/ {7 b" q$ x/ z
  63.    
    + e# f8 r* v; G- a* s
  64.     /* 释放动态内存 */    ! G) ?  T0 X1 S4 L8 l# v" r
  65.      GUI_ALLOC_Free(hMem);
    + {1 O+ T* i" c7 m$ U4 h: e
  66.      f_close(&file);
      r1 g' m& k5 H' K0 {1 K) J- v, H/ e
  67. }! q. U) P8 @1 x# @
  68. ) s( F" b2 e- y& l3 s5 g/ a
  69. /*
    5 C' T6 J# r/ |: R
  70. *********************************************************************************************************
    ! V! N( e# y# i& B9 p( t
  71. *    函 数 名: MainTask" S3 G9 V2 l$ J, b- f
  72. *    功能说明: GUI主函数
    + r' B5 F0 E/ d
  73. *    形    参:无/ A$ K+ s+ X5 c. I
  74. *    返 回 值: 无
    ' _" G, v4 ^) l( L# `% |  w5 B) J
  75. *********************************************************************************************************
    # d# Q% b, ]; s, Q4 k# s
  76. */
    5 l* o) \3 F& d5 c6 r% a
  77. void MainTask(void)
    ! f: A0 l( J! `, b
  78. {   
    ! Y# O! [5 M2 Y+ K7 J  z7 G8 g1 W8 U
  79.      GUI_Init();
      W& T9 q& ~! l; j* E
  80. 7 d* ]) q% }! p0 J: l4 }+ L
  81.      /* 设置皮肤函数 */+ g0 B- m: F1 }
  82.      PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);
    + _: P# j( p: R4 m3 O' v
  83.      FRAMEWIN_SetDefaultSkin(FRAMEWIN_SKIN_FLEX);0 Z. E% O  K. @5 w( u
  84.      PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);! b. S/ A( u  s
  85.      BUTTON_SetDefaultSkin(BUTTON_SKIN_FLEX);0 e: E, g" ?. m
  86.      CHECKBOX_SetDefaultSkin(CHECKBOX_SKIN_FLEX);
    7 t; V4 g) R" R2 V4 n3 _+ w* Q
  87.      DROPDOWN_SetDefaultSkin(DROPDOWN_SKIN_FLEX);
    # X2 R1 K% K' m$ D0 X  u
  88.      SCROLLBAR_SetDefaultSkin(SCROLLBAR_SKIN_FLEX);
    " D0 |& t0 Z0 X; Z
  89.      SLIDER_SetDefaultSkin(SLIDER_SKIN_FLEX);
    & R4 |- a  A% N6 j
  90.      HEADER_SetDefaultSkin(HEADER_SKIN_FLEX);# l. f5 j7 J( S
  91.      RADIO_SetDefaultSkin(RADIO_SKIN_FLEX);
    ) l1 V- W0 J: O' U. }" b3 J
  92. + f  E% ]+ x3 @; i
  93.      /* 读取并显示文件 */
    6 ^, K! U  p, R8 p2 k  N2 z/ E
  94.      _ShowStreamBitmap("logo.dta");- |: ?: e0 w, y/ D: k6 ~3 d+ `, E

  95.   |3 [9 p$ ^- j$ P
  96.      while(1)( {0 M- d2 W8 m4 w$ s
  97.      {                 " ]% R! ?4 K8 t! F
  98.          GUI_Delay(100);       ( d' N$ _) x( t1 t! G. Q& [
  99.      }% L( a3 Y) z" Y' b- V
  100.   ~7 L% w$ |3 z3 z9 F
  101. }
复制代码
    显示效果如下:
9.9.png

- o; z3 m0 X2 i8 V
9.3  实验总结
    流位图在一些应用中比较有用,比如要在按钮上面显示图片,我们不需要将其用位图转换器转换成相应的C文件,并下载到内部flash进行显示,我们可以将其放到外部SD,flash等存储器进行加载显示,这个实验尝试了一下在按钮上面显示,就是显示不出来,后面有时间再做尝试。

! t5 H+ U+ O' t# ^, m
3 o0 g( G; Q% z- J1 C' g2 X: O, e( _& c# d5 z
赞 收藏 1 评论0 发布时间:2015-1-13 16:43

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版