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

【安富莱STemWin教程】第13章 GIF图片显示

[复制链接]
baiyongbin2009 发布时间:2015-1-15 14:22
本帖最后由 baiyongbin2009 于 2015-1-15 14:23 编辑 ; r9 S0 F/ ~' A) _( K3 f" \
3 {& d. N. B3 k
特别说明:完整STemWin的1-60期教程和配套实例下载地址:链接
第13章      GIF图片显示
. Q5 ]  o! j! r1 X1 d' c4 B5 t6 w
    本期主要讲emWin支持的GIF图片的显示,官方支持的主要有两种显示方法,一种是从外部存储器读取数据到内部存储器,然后来显示图片,这种的显示速度要快些,另一种方法是直接从外部存储器读取数据并显示,这种办法的好处就是不要大的RAM需求,每次读取一些数据显示一次,坏处就是显示速度比较的慢。
    这里将2MB的外部SRAM做为emWin的动态内存。
    13. 1  GIF图片支持
    13. 2 绘制已经加载到存储器的GIF图片
    13. 3 绘制无须加载到存储器的GIF图片
    13. 4 实验总结

# Z; x: B3 G- _. c1 X
13.1  GIF图片支持
    20世纪80年代,CompuServeInformation Service开发出了GIF文件格式(图形交换格式)。
    它设计用于跨数据网络传输图像。GIF标准支持隔行扫描、透明、应用定义数据、动画以及原始文本渲染。emWin将忽略原始文本或应用特定数据等不受支持的数据。GIF文件使用LZW (Lempel-Zif-Welch)文件压缩方法来压缩图像数据。这种压缩方法运行起来不会丢失数据。输出图像与输入图像完全相同。
    图形库首先对图形信息进行解码。如果必须绘制图像,解码流程将花费相当长的时间。如果在窗口管理器经常调用的callback例程中使用GIF文件,则解码流程可能花费相当长的时间。通过使用存储设备可缩短计算时间。最好的方法是先将图像绘制到存储设备中。在这种情况下,将只进行一次解压缩。
    emWin的GIF解压缩例程大约需要16千字节动态分配的RAM进行解压缩。绘制图像后,将释放用于解压缩的RAM。
13.1.1      GIF格式图标转换
    某些情况下,将GIF文件作为C文件添加到项目中非常有用。对此,可完全按照前面介绍的“JPEG文件支持”下的相同方式来执行。下面举一个例子方便大家理解。比如我们要转换下面的GIF图片
13.1.jpg
2 |8 t) d& _" t( Y0 ^. \
l  打开软件加载上面的图片
13.2.jpg

% e' V( s% y1 b
l  加载后点击Convert即可,点击后没有任何现象,直接去图片所在的文件夹找即可
13.3.jpg

! ]% h6 J1 `! ~7 {
实际运行代码如下(图片数据就不贴出来了,看本期教程配套的例子)
  1. GUI_GIF_INFO InfoGif1;2 C0 _; n5 m5 G! j4 m) t! l
  2. GUI_GIF_IMAGE_INFO InfoGif2;
    7 a) M! |$ z3 ^5 C- u: R
  3. & |  |# ~# ^) }) `& G5 K
  4. void MainTask(void)
    6 f" ]2 N7 Q8 b4 Q& I' g& ~* I
  5. {   
    , g: s9 c# J  H( f( G( J/ K
  6.      int i = 0;
    6 O; T! ^+ G1 \' ~
  7.   S. @6 \& F. ?( C+ j
  8.      GUI_Init();1 s$ s% P) j- @& x9 a$ I

  9. 4 V5 V( s8 ^9 `( T; [
  10.      GUI_GIF_GetInfo(_ac4, sizeof(_ac4), &InfoGif1); (1)
    ; t$ m# o0 ^% q
  11.      while(1)' R2 ]. V5 _/ U0 I( m" S) ]( j
  12.      {- P; H+ d# ]' x; ^
  13.          if(i < InfoGif1.NumImages)
    7 n. X$ u: J& R% v
  14.          {+ ?: R6 K2 ^9 z
  15.               GUI_GIF_GetImageInfo(_ac4, sizeof(_ac4), &InfoGif2, i);(2)
    ( D6 e- o8 N7 F* J/ H
  16.               GUI_GIF_DrawSub(_ac4, (3)
    * O6 P; u' X; W
  17.                             sizeof(_ac4),
    $ e7 e7 M) p- R; P# {
  18.                             (LCD_GetXSize() - InfoGif1.xSize)/2,
    - `7 p- |* f! y+ E$ c
  19.                             (LCD_GetYSize() - InfoGif1.ySize)/2,& p8 M: k2 [3 \/ Y) S: p3 V
  20.                             i++);9 P  A# k3 \3 m7 Q8 g9 ]1 g0 i
  21.               /* 这个函数要注意,主要是设置每个GIF子图像的时间间隔的。*/
    ' p$ o- R! E, @$ h
  22.          GUI_Delay(InfoGif2.Delay*10);                      (4)
    / \; U6 K- _0 Y( c% C
  23.          }  J6 W  ~4 V8 C' [  o' D
  24.          else1 x' r' _0 o% ]! ~7 U5 l! _
  25.          {, ^0 K1 F/ X- j

  26. 9 l; Z1 m7 p# e" l! k! Q4 Z. v2 F4 @
  27.               i = 0;
    2 U1 O! [. g) W# O
  28.          }! V. Z, A% o0 E
  29.      }
    & |& v3 S  s# {* R" a7 r$ C5 c# \8 }
  30. }
复制代码
1.     这个函数用于获取GIF图像的信息。获取的信息填充到结构体GUI_GIF_INFO中,此结构体的定义如下:
, A( q9 K3 p2 W7 W# c$ {% Y  B
13.4.png
    这个里面有个错误:不是XSize和YSize,而是xSize和ySize(这个错误一直没有更正)。
2.     获取GIF图像的信息,获取的信息填充给结构体GUI_GIF_IMAGE_INFO,结构体的定义如下:

( ?3 U- W/ p$ k5 A! ^
13.5.png
3.     绘制GIF的每个子图像。
4.     这里延迟时间参数InfoGif2.Delay要乘以10,主要是因为系统的滴答时钟节拍是1ms,而GIF图像的时钟节拍是以10ms为单位的。所以这里要乘以10。
5.     模拟器编译会出现以下错误信息(fatal error C1076:compiler limit : internal heap limit reached; use /Zm to specify a higher limit)

, ]/ i; V) t( n* B) T
    13.6.jpg
     解决办法如下:
    第一步:点击Project –>settings选择C/C++,在Project Options中加入/Zm1000(要从末尾进行加入,也就是/c后面,点击OK后会自动的加到/c前面)
13.7.jpg

5 ~3 V9 c) n+ h- Q% k: c# P: R! Z
    为什么改,大家可以看下msdn中的说明:http://msdn.microsoft.com/zh-cn/library/bdscwf1c。这个不属于咱们要介绍的范围,有兴趣的可以在网上搜索上面的错误信息进行了解。
实际显示效果如下:
13.8.png
, b8 V* B& t8 E! h; O5 a
13.1.2      GIF存储器方式显示
    对于GIF格式的图片,一般用存储方式显示即可,只有显示的图片不是很复杂,这种方式显示速度也比较快。当前STemWin支持的GIF图片 API函数如下:

. M) v0 G) c) r6 S/ o
13.9.png
9 ?# A% @/ T- n. \' l
0 d; D; P5 z; j
赞 收藏 1 评论13 发布时间:2015-1-15 14:22

举报

13个回答
沐紫 回答时间:2015-1-15 14:23:57
教程真多,貌似天天过来发,坚持这么久不容易,点个赞
baiyongbin2009 回答时间:2015-1-15 14:26:07
本帖最后由 baiyongbin2009 于 2015-1-15 14:27 编辑
* c! g8 z0 l$ J! d2 W2 S) O* z( n, {1 ~) t6 g$ G
13.2  绘制已经加载到存储器的GIF图片
    将图片加载到存储器后进行显示比较的耗内存,所以这里就使用开发板外置的2MB SRAM做STemWin的动态内存空间,并通过相应的API函数申请动态内存来加载SD卡等外部存储器中的GIF图片。申请和释放STemWin动态内存的方法如下:
  1. /* 申请一块内存空间 并且将其清零 */# X0 ^$ N( R9 a! ?1 ?
  2. hMem = GUI_ALLOC_AllocZero(100000);
    2 o! O9 I% b7 h/ j( t; T2 p3 n
  3. /* 将申请到内存的句柄转换成指针类型 */
    " W. a2 n8 a9 i2 v1 f; Z, O
  4. _acBuffer2 = GUI_ALLOC_h2p(hMem);1 J7 L( N& T1 `7 V6 W- w% b) }
  5. /* 释放申请的动态内存  */5 n4 M$ e1 B! \! H% G
  6. GUI_ALLOC_Free(hMem);
复制代码
    这里还用上面的图片作为显示对象。先把这个图片放到SD卡中,然后通过程序把这个图片数据全部的加载到SRAM中,最后在屏上进行显示。这个工程的实现主要分为如下三个部分:
Ø  SRAM和SD卡及其文件系统的初始化
Ø  图片的加载以及显示函数
Ø  主函数
    下面把这三部分详细的讲解下:
l  SRAM和SD卡及其文件系统的初始化,这部分函数与上面第11章的11.2小节一样。
l  图片的加载以及显示函数
  1. /*6 H0 \/ `- R" z% G8 |
  2. *********************************************************************************************************$ q# R, `1 B  p0 R0 c3 P0 c
  3. *    函 数 名: _ShowGIF
    1 a" v8 Y9 `* F$ K3 }4 x( l
  4. *    功能说明: 显示GIF片  m- X7 {: Z( V
  5. *    形    参:sFilename 要显示的图片名字
    + }2 R) U6 P9 A4 v2 g
  6. *    返 回 值: 无5 ?% o7 h. f' p1 V/ R3 j
  7. *********************************************************************************************************8 P' u" C" f/ `7 W' H& [8 X6 `$ t$ N- J
  8. */4 D2 W2 B" a( E4 N2 ?6 a1 C
  9. static void _ShowGIF(const char * sFilename)
    ; \. X& X; o  @# |) O' [
  10. {
    : G# x$ Q& r, ]* Q. F: R; w. b
  11.      GUI_HMEM hMem;/ F- ]( \( ?5 a$ N  S: ]3 M; [
  12.      char *_acBuffer2;
    : ^( f8 ~$ S  Q2 a' ]2 z/ b) y; H
  13.      uint8_t i;
    * t' U7 o; g& `4 l2 I" I0 ^
  14. 1 [# f4 @1 ^3 U9 F+ w
  15.      /* 申请一块内存空间 并且将其清零 */
    * a  J+ k+ M* V  t& O. ]8 `! j" O
  16.     hMem = GUI_ALLOC_AllocZero(1024*1024);# b, Z2 q1 _5 [: p$ ?3 ~
  17.      /* 将申请到内存的句柄转换成指针类型 */' C) e7 Z' T9 [
  18.      _acBuffer2 = GUI_ALLOC_h2p(hMem);7 q! z" T& B/ S
  19. 2 F- x/ g# J" |9 G! z
  20.    
    ( V4 X& o! w* d7 Q6 K3 [3 w5 n2 H
  21.      /* 打开文件 */        - n. V# f8 \9 ]$ I& U4 s/ [
  22.      result = f_open(&file, sFilename, FA_OPEN_EXISTING | FA_READ | FA_OPEN_ALWAYS);
    # m1 B& f! l5 k/ Z& c& V! g
  23.      if (result != FR_OK); N" e7 x$ G% e* w
  24.      {
    1 d1 j( |1 X# [3 O8 [+ _
  25.          return;  M1 e3 B" E- R6 O  O4 p
  26.      }6 a* t# `7 x  d8 S' w+ E/ I. Q
  27. ' i- q  q0 }, o$ T1 A1 h, _% {/ [$ K
  28.      result = f_read(&file, _acBuffer2, file.fsize, &bw);- Y) A8 I4 d0 f/ p' h+ p5 p
  29.      if (result != FR_OK)
    2 _2 ^/ m/ h( R+ N$ N7 j
  30.      {
    $ g& W: c! {/ k( @1 Y8 Y
  31.          return;$ C9 ]9 {$ v, x4 M5 @: w
  32.      }
    8 G) z5 J* A- T; \
  33.     4 g' u/ Q, J5 Q8 n
  34.    GUI_GIF_GetInfo(_acBuffer2, file.fsize, &InfoGif1);
    4 E1 x2 s& |6 T6 V, n
  35. 0 g* C6 S& `) A& D$ C* D7 @2 `# K/ U
  36.    while(1)
    , }' Z7 n3 `# R+ w* t
  37.    {
    # {) e  A& C* R7 b4 ~- q5 T+ F
  38.          if(i < InfoGif1.NumImages)8 s* n% P: h/ ]8 g1 N: b3 p7 r
  39.          {% y# |/ O- i) l, o, G
  40.              GUI_GIF_GetImageInfo(_acBuffer2, file.fsize, &InfoGif2, i);" |& s+ q) z0 h4 Z! t  A
  41.              GUI_GIF_DrawSub(_acBuffer2,! g1 W1 N0 z# A  g- E
  42.                               file.fsize,
    & V- w4 l1 _1 q/ Y6 z
  43.                               (LCD_GetXSize() - InfoGif1.xSize)/2,1 N  a" l5 \8 z  Y
  44.                                  (LCD_GetYSize() - InfoGif1.ySize)/2,9 P2 d# C% X1 S2 S5 t
  45.                               i++);% U# l) m7 ?. y$ c1 H- D% U2 `" J
  46.                       ) l" ]+ m% o+ Z, W* W
  47. //            GUI_GIF_DrawSubScaled(_acBuffer2, (1)
    + u. r  f$ X# F+ R4 r
  48. //                                  file.fsize,
    4 r0 j7 q6 \' c- |- {" V' k+ e
  49. //                                  (LCD_GetXSize() - InfoGif1.xSize*3)/2,
      g' ]4 X; s" x7 x5 `
  50. //                                     (LCD_GetYSize() - InfoGif1.ySize*3)/2,
    . s) z5 D. r7 t9 M  C% N
  51. //                                  i++,/ ?3 a7 `# ~2 X, [, t; ]( r( L
  52. //                                  3,+ O& H. j3 Q$ f5 e
  53. //                                1);
    " Q' d' q  X4 R% P1 x
  54.             
    $ y5 P: |$ X* r' s5 M
  55.               GUI_X_Delay(InfoGif2.Delay*10);                  
    1 L/ s; M8 a! Z+ F7 Z: W& t: s
  56.          }5 }! v% n8 f2 I0 g$ p
  57.          else
    - h5 T- J& Y: c% O
  58.          {
    8 o: ^5 l3 A3 G; Q
  59.              i = 0;$ ~5 c) M4 R* x. k
  60.          }
    3 c7 ?8 S2 v8 ^
  61.      }% o$ ]; t' L. A# F* q! o
  62.   Q* G6 G; U$ ^7 _
  63. //   GUI_ALLOC_Free(hMem);% P4 _7 }  t, m
  64. //   f_close(&file);2 g' R9 j% `* p! ?2 S. u- v: q4 S
  65. }
复制代码
1.    根据需要,大家可以选择以一定的放缩比例显示GIF图片。
l  主函数
  1. /*
    3 d2 z( _/ Y1 o$ b: H1 \- D" q
  2. *********************************************************************************************************
    $ r* M$ ]$ P' ?) |
  3. *    函 数 名: MainTask1 l: W  s* ]8 f+ S, r- ^' H
  4. *    功能说明: GUI主函数
    3 E( t3 h& r9 ?) V# N4 Y2 v
  5. *    形    参:无
    ' i: o% {3 J! }- Q
  6. *    返 回 值: 无
    ) O$ ^+ ~+ m1 o; M
  7. *********************************************************************************************************
    5 U! x( P! I# I( |* f5 ]: L- o
  8. */8 z/ d, D8 v) @: c
  9. void MainTask(void)4 h" {/ S3 B2 a$ b
  10. {   
    ! r$ i1 j" D, w* E( B9 \
  11.      GUI_Init();
    - I( l9 Z7 y3 _) f/ e7 T: L
  12. + W2 o, ^8 B  Q2 i
  13.      /* 设置皮肤函数 */1 b* g8 {0 {; K4 {
  14.      PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);2 G" n! l8 E6 @) |# {1 u
  15.      FRAMEWIN_SetDefaultSkin(FRAMEWIN_SKIN_FLEX);
      {* A* m( M6 i
  16.      PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);  I, c$ a1 |7 ]9 W( h, a: V
  17.      BUTTON_SetDefaultSkin(BUTTON_SKIN_FLEX);" L6 q7 x" R% {5 `
  18.      CHECKBOX_SetDefaultSkin(CHECKBOX_SKIN_FLEX);
    2 `3 L* c  O% F! B8 i! J& @+ w! T: D+ g9 c
  19.      DROPDOWN_SetDefaultSkin(DROPDOWN_SKIN_FLEX);
    ( b. p* B6 i- q' ]9 o9 f
  20.      SCROLLBAR_SetDefaultSkin(SCROLLBAR_SKIN_FLEX);
    5 {& ~) c6 [, ^- h
  21.      SLIDER_SetDefaultSkin(SLIDER_SKIN_FLEX);
    + ?5 y" ^7 R/ |  f6 k" H
  22.      HEADER_SetDefaultSkin(HEADER_SKIN_FLEX);
    " R" E8 W3 ]7 P! ?* R; j) a
  23.      RADIO_SetDefaultSkin(RADIO_SKIN_FLEX);
    5 _  L6 c7 ]/ W, g# R8 ^2 j- X

  24. # K& q' G8 J% ]% j5 L& A
  25.      while(1)
    0 x( Z5 ]  y4 j; G
  26.      {                 
    ' B$ ?* c% s% `& K+ K8 W4 |
  27.           _ShowGIF("4.gif");   
    & v. I' h# u& X5 f
  28.      }3 s% ]; `* b& s, D% G8 }

  29. 8 {. V1 Y5 Q( `) r: q/ L
  30. }
复制代码
实际现象效果如下:
13.10.png

( j9 N+ L( t% t% l, v  C
放大三倍后的显示效果如下:
13.11.png

! ^% d: _# g0 Z0 k0 C" O6 I+ y
baiyongbin2009 回答时间:2015-1-15 14:29:45
13.3   绘制无需加载到存储器的GIF图片
    绘制无需加载到存储器的GIF图片方式可以有效的解决内部动态内存不够的情况,不过缺点也很明显,图片的显示速度很慢。这种方式一般是每次读取一行像素的数据,然后进行显示。这个工程的实现主要分为如下三个部分:
Ø  使用芯片内部的SRAM作为动态内存
Ø  图片的加载以及显示函数
Ø  主函数
    下面把这三部分详细的讲解下:
l  使用芯片外部的SRAM作为动态内存,这部分函数与上面第11章的11.2小节一样,由于GIF比较的消耗内存,这里和BMP不同也需要使用动态内存。
l  图片的加以及显示函数。
  1. static char _acBuffer[0x2000];; R+ u; R. r$ l! o6 y
  2. GUI_GIF_INFO InfoGif1;
    1 k6 v7 p2 @* I( J1 K) Z
  3. GUI_GIF_IMAGE_INFO InfoGif2;
    ; t* V: y  g  F, w4 w4 t8 T
  4. 6 G" J! C% ?8 W8 L
  5. /*) p. K# o4 S5 o3 r
  6. ********************************************************************************
    6 y9 r) l2 N+ H6 W' n0 G- {, E
  7. *
    ! V0 i5 Q+ m1 _) t& r! X
  8. *       _GetData
    2 T1 r3 M, T7 F/ k, O
  9. *
    1 K* O9 i, `# D4 I3 A
  10. * Purpose:. X# w6 E* J, V9 M9 Q
  11. *   This routine is called by GUI_GIF_DrawEx(). The routine is responsible: R% h  K9 K! y
  12. *   for setting the data pointer to a valid data location with at least) ]+ M: \9 I, T/ M& P$ T
  13. *   one valid byte.
    7 a" S+ B2 y' k1 B: ]6 m: o
  14. *( x2 s4 r8 i8 J3 R  F) m8 Y/ H
  15. * Parameters:
    , P7 x- u; \7 N4 q5 n1 n9 n
  16. *   p           - Pointer to application defined data.6 j: Q6 ?# Q3 o/ l
  17. *   NumBytesReq - Number of bytes requested.
      Q; L; F! X+ a; ?  D, C# C
  18. *   ppData      - Pointer to data pointer. This pointer should be set to
    4 L. I  o( ?4 |9 V
  19. *                 a valid location.* v+ e8 n, H3 m& J6 W+ b$ S! w
  20. *   StartOfFile - If this flag is 1, the data pointer should be set to the" \" F+ U3 D8 |6 h
  21. *                 beginning of the data stream.
    * C) F* Y. D% l0 t3 D) ^7 Z6 t
  22. *# r8 W7 M5 c8 ?! w% a, m
  23. * Return value:
    # D% Y& o. v* V! j
  24. *   Number of data bytes available.) S2 c5 n' ~7 |
  25. *********************************************************************************
    . G8 P9 U. o  c$ u6 c8 N4 O& F) x: l
  26. */# O. b, F; a' ?
  27. static int _GetData(void * p, const U8 ** ppData, unsigned NumBytesReq, U32 Off) {1 k6 r2 ?4 q3 R7 j& q5 d7 G7 m+ j, F
  28.      static int FileAddress = 0;
    ' {' M$ R! v3 e  Q/ u7 [
  29.      UINT NumBytesRead;
      `+ z8 s3 h! s( Q1 ^, l' v
  30.      FIL *PicFile;
    7 x- ^1 e4 `. o
  31. & ]7 {) [! {) A3 `, S8 ?1 c
  32.      PicFile = (FIL *)p;
    4 s( K3 |- e# W0 H. ?5 n

  33. " m7 |2 F+ C: X' c4 ^( {
  34.      /*# p1 Z9 ^! G# C: W. H! C
  35.      * Check buffer size
    2 Y  T; }& w0 m+ F2 ?
  36.      */
    / g9 m+ x- y( T+ B; p3 S7 j3 p
  37.      if (NumBytesReq > sizeof(_acBuffer)) {! m; c' x0 f6 \' X. p
  38.      NumBytesReq = sizeof(_acBuffer);  N$ q# }$ j) C( s/ s1 J
  39.      }! L+ z9 D. e0 x, R' D

  40. # J7 V+ y4 l0 Z7 q. O! m6 [

  41. 7 Z, v; z8 i9 d
  42.      /*
    * H* a$ l) |/ \5 h; x3 N3 y+ O
  43.      * Set file pointer to the required position
    " n$ S1 {. D9 ^# G
  44.      */3 f' [& `( E! T, _
  45.      if(Off == 1) FileAddress = 0;% I" W$ ~4 |& V3 {& H0 L
  46.      else FileAddress = Off;
      H! B8 Z$ X( i9 M
  47.      result =f_lseek(PicFile, FileAddress);0 ^3 G5 P' ~; _# V

  48. 8 F9 M- I% |  o2 G0 E

  49. . P4 y' |3 n3 i, q
  50.      /*4 g1 g3 A8 c5 `( t+ K) ^6 ^7 O
  51.      * Read data into buffer
    4 `. |# [/ l( e7 i6 Z6 @8 X
  52.      */2 i# T0 @, l0 p9 l
  53.      result = f_read(PicFile, _acBuffer, NumBytesReq, &NumBytesRead);  O4 f. m7 c( w: t6 N3 k: F
  54. - O! z; A1 B' k! _/ N
  55.      /*+ `% D" U# N; u1 l
  56.      * Set data pointer to the beginning of the buffer
    ! Z2 @3 D9 C# f! c8 w* {
  57.      */1 a2 m4 p. J( l3 p5 Z' o
  58.      *ppData = (const U8 *)_acBuffer;
    : c' Z4 ~+ |; R3 y
  59. / {/ o# x  u; E& T$ z
  60.      /*
    6 m/ D1 ]: ~8 g% ]) E( r, X5 `
  61.      * Return number of available bytes
    2 N3 Y! w7 j8 S' v
  62.      */
    9 R; r7 Z0 [  b3 }& N# y; O' g
  63.      return NumBytesRead;
    2 o. X6 _! {* L1 w  L4 k1 W, H7 H
  64. }
    $ q( W8 k, M; r& k& T; U  R

  65. ( k6 Y  ?* ?5 N, w/ x
  66. /*7 [; j8 V$ d( S' e( I/ k6 M/ S
  67. *********************************************************************************************************
    3 q4 C" g* b# ]8 P  e
  68. *    函 数 名: _ShowGIFEx4 ~  i9 ^( p' N) i2 g# x
  69. *    功能说明: GIF图片显示1 ^( i. C+ T% J8 s
  70. *    形    参:sFilename 文件名
    ' o* g2 ]6 ^1 r% u
  71. *    返 回 值: 无( ^# o) R# K7 B: f/ k9 a8 K1 @# m
  72. *********************************************************************************************************
    , z* F1 z( f$ I+ r& I
  73. */1 ]  g* Z4 ]( ^1 Y! F- `+ p  k
  74. static void _ShowGIFEx(const char * sFilename)
    : \2 G7 |& z1 u3 R' t
  75. {   9 f- T: |. k7 x- u$ R
  76.      OS_ERR err;
    & X  V  O6 Y1 x  s- E. }
  77.      uint8_t i;
    7 E' L5 n% \1 A) _5 V/ R
  78. * J/ d% Y. K4 V) z* m9 L4 ]: t! s: K
  79.      /* 打开文件 */        4 f0 @' t' H! S8 @
  80.      result = f_open(&file, sFilename, FA_OPEN_EXISTING | FA_READ | FA_OPEN_ALWAYS);
    " G: X( H& K1 {% D
  81.      if (result != FR_OK)+ Z0 _1 u$ o6 v' F  j! o
  82.      {
    / e8 u2 {; p+ s
  83.          return;
      O, Z# V" N: l( @, z  f3 A$ R7 v
  84.      }4 S$ I1 q, g8 j1 V& C# p. ^
  85.     9 ?. _/ |# h1 B
  86.    GUI_GIF_GetInfoEx(_GetData, &file,&InfoGif1);$ p' P; F% t( R* x/ b" p* A+ V9 u
  87. 4 {% g* B2 D5 ]/ e% \: Z
  88.    while(1)" g1 D$ [; w9 S/ ~' h( I
  89.    {
    $ d( q/ L6 k! m5 y% X% T
  90.          if(i < InfoGif1.NumImages)9 i- L, b9 ]8 ~( G7 m
  91.          {
    - c' `) T, P; \; W) C
  92.               //OSSchedLock(&err);            & y8 S  D) V$ F* T; X
  93.              GUI_GIF_GetImageInfoEx(_GetData, &file, &InfoGif2, i );
    6 o, P6 ?$ G  c% R9 h+ {
  94.              GUI_GIF_DrawSubEx(_GetData,
    * T+ |" n% C5 A4 n1 o5 @! @2 M
  95.               &file,1 z9 k0 [1 \: ~
  96.                                 (LCD_GetXSize() - InfoGif1.xSize)/2,9 n8 J" P4 I) \- p
  97.                                  (LCD_GetYSize() - InfoGif1.ySize)/2,
    ) w9 B* z6 x. n, ?
  98.                                 i++);& ?& p" i* E$ K- q- r: {
  99.             
    0 a8 ~$ E/ \% E2 I) N
  100.              //OSSchedUnlock(&err);           
    5 H& x: e# u8 a/ T
  101.               GUI_X_Delay(InfoGif2.Delay*10);                  
    6 N& ?& K* D! B" G- j5 b
  102.          }  p3 U1 p2 d3 B, m$ S5 O& i
  103.          else
    6 Q) t- ^# u5 M5 \5 I
  104.          {, D+ b) O# @+ m1 m) ]( d) p
  105.              i = 0;
    3 r9 O0 h* z' _, M. u7 o) _
  106.          }& v$ J& j3 Y9 }& l
  107.      }; _% T  ?3 K- o/ V: k6 I
  108. 0 P9 I6 Y: T8 }5 i7 C
  109. //   f_close(&file);+ f5 z/ u3 f( S2 |
  110. }
复制代码
l  主函数
  1. /*8 R, G% y5 f& A& O
  2. *********************************************************************************************************
    : u: n9 c# P* E9 z4 x2 z" B* B
  3. *    函 数 名: MainTask9 D: A% L& s1 |5 a7 O7 P
  4. *    功能说明: GUI主函数  b/ o* N, z' p# w
  5. *    形    参:无. Y7 c2 {0 f4 d
  6. *    返 回 值: 无. I9 ~) n& p9 ^/ q' N
  7. ********************************************************************************************************** x( w; \7 k, j- u9 ^/ [. n
  8. */
    ( ~4 }% w! G$ T
  9. void MainTask(void)
    2 U# j$ u2 X$ h3 T/ H
  10. {   
    9 ?6 g5 y7 X4 G; T4 J' q
  11.      GUI_Init();
    ; O# n! Y, c6 s. A3 g
  12. 0 R2 G# g) f0 V! U/ A4 J+ x7 b
  13.      /* 设置皮肤函数 */( L8 n0 \" L+ P
  14.      PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);
    0 D* ^6 I. M# b" t  @2 [( u% t" ]
  15.      FRAMEWIN_SetDefaultSkin(FRAMEWIN_SKIN_FLEX);
    6 l" n$ o! l! s- M; |
  16.      PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);
    ' m6 g) \1 n) y- H
  17.      BUTTON_SetDefaultSkin(BUTTON_SKIN_FLEX);6 n/ e4 K7 m/ ?9 [3 b/ e
  18.      CHECKBOX_SetDefaultSkin(CHECKBOX_SKIN_FLEX);
    1 F8 J; p4 z9 c; a$ l
  19.      DROPDOWN_SetDefaultSkin(DROPDOWN_SKIN_FLEX);' J/ n6 R2 N$ S1 F8 M1 o
  20.      SCROLLBAR_SetDefaultSkin(SCROLLBAR_SKIN_FLEX);7 f2 v6 a$ T& d/ v: h" X7 r: B
  21.      SLIDER_SetDefaultSkin(SLIDER_SKIN_FLEX);
    ! }9 N9 G; X- [% s" z
  22.      HEADER_SetDefaultSkin(HEADER_SKIN_FLEX);
    9 [# A: P$ z) O3 G2 j
  23.      RADIO_SetDefaultSkin(RADIO_SKIN_FLEX);+ I2 r* A! {& T/ }* f. M. \3 ]
  24.    
    7 v! Y7 ]* B1 m1 f7 _5 k
  25.      while(1)2 O' q2 I5 n" W5 I
  26.      {                 
    2 W! t' Q: n. C- q7 D
  27.          _ShowGIFEx("2.gif");  : I0 V" Y1 J) C; n- B& J  l
  28.      }
    7 n# B6 Q/ P# t+ m5 J' [3 o0 i
  29. 2 X; C& s+ H9 }# F' p, e; f
  30. }
复制代码
实际显示效果如下:
13.12.png

: U  p( H% ^' W8 O: r- r
这个图片比较大,有2.5MB左右,所以刷新速度比较慢,第一次运行需要断电后重启进行显示。
13.4  实验总结
    有兴趣的可以了解一下GIF压缩方面的知识。如果只是API应用的话,这部分知识还是比较容易学会的。GIF动态图片用到的场合也比较多。
. Q1 n2 f% y( Q: T
baiyongbin2009 回答时间:2015-1-15 14:30:53
沐紫 发表于 2015-1-15 14:236 `* p  d- x* ]9 U- b& E
教程真多,貌似天天过来发,坚持这么久不容易,点个赞
% _1 i. g- A/ `7 b4 Q, h
谢谢支持!!
youxiaoxiang 回答时间:2015-3-12 14:49:31
你好,我通过你的教程显示出了GIF图片,但是不会动。请问是什么问题呢,图片是有显示的
大浪10010 回答时间:2015-3-12 15:22:08
真不错,,,
baiyongbin2009 回答时间:2015-3-12 15:25:26
youxiaoxiang 发表于 2015-3-12 14:49, x  K$ a# u" E& o
你好,我通过你的教程显示出了GIF图片,但是不会动。请问是什么问题呢,图片是有显示的 ...
+ s2 q) B& [9 Z
找个比较小的gif图片再试试,看看是否是动态内存不够。
寂寞如她 回答时间:2015-3-12 17:28:50
好帖,必须顶
youxiaoxiang 回答时间:2015-3-13 10:38:53
baiyongbin2009 发表于 2015-3-12 15:25: I/ m/ S2 V$ T
找个比较小的gif图片再试试,看看是否是动态内存不够。
0 J& x$ ]/ V; V; M
我现在找了一个320*240的GIF图,大概是90K大小,放在模拟器上显示很流畅,但是板子上就差很多,刷新很慢,有办法吗
wyxy163@126.com 回答时间:2015-3-14 13:43:55
提示: 作者被禁止或删除 内容自动屏蔽
wyxy163@126.com 回答时间:2015-3-14 13:44:19
提示: 作者被禁止或删除 内容自动屏蔽
有时浑身不舒服 回答时间:2016-9-20 11:16:41
楼主,在第一段代码里,_ac4是什么?编译也出错了,我就想知道gif转换成的c文件怎用使用?mainTask函数里没有用到啊
zbber 回答时间:2016-9-20 12:13:51
谢谢分享 赞一个
4 ~3 T+ |8 j0 r) R) ~; `
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版