硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2595|回复: 2
收起左侧

[emWin] 为什么使用存储设备后jpeg图片不显示的分析

[复制链接]

12

主题

16

回帖

52

积分

初级会员

积分
52
发表于 2018-6-6 10:14:31 | 显示全部楼层 |阅读模式
本帖最后由 来俩不甜的 于 2018-6-6 10:16 编辑

场景:使用stm32f407ve, cpu本身有192KB RAM,无外接ram。现象:jpeg显示大图可以,但拉窗现象严重。小图直接不显示。
分析:粗浅的见解,有不对的地方恳请大佬指出。

  1. // 使用存储设备发现不显示图片
  2. // 猜测是内存不足,分析如下:
  3. /*
  4. * jpeg解码本身就需要约33KB,还要再加上图片的 x大小 * 80bytes
  5. * 那么此处horse.jpg解码需要的ram = 33 + 160 * 80 / 1024 = 45.5KB
  6. * 这45.5KB会在GUI_JPEG_Draw()函数用到
  7. * horse.jpg : 160 * 128   25821bytes(25.2KB)
  8. * GUIConf.c中为emwin分配的内存是100KB
  9. * 那么读出这幅jpg图片要用25.2KB
  10. * 然后创建存储设备  xsize * ysize * bpp / 8 = 160 * 128 * 16 / 8 = 40KB
  11. * 这两步就使用了65.5KB,再加上emwin本身消耗的内存(不知道,可参考安富莱v6教程31页)
  12. * 剩余内存可认为是30KB < 45.5KB,会导致解码失败,因此图片不会显示
  13. * 前面定义的sd卡路径中,大图为什么显示?
  14. * 因为这里的存储设备分配失败,有足够的内存来解码jpeg,因此显示,但刷新速度肉眼可见,
  15. * 使用体验非常差
  16. */

  17. void MyDemo(void)
  18. {
  19.         FRESULT res;
  20.         UINT br;
  21.        
  22.         char *_acBuffer;
  23.         GUI_HMEM hMem;
  24.         GUI_MEMDEV_Handle hMemJPEG;
  25.         GUI_JPEG_INFO JpegInfo;
  26.        
  27.         res = f_open(&file, g_strJpgPath2, FA_OPEN_EXISTING | FA_READ);
  28.         if (res != FR_OK)
  29.         {
  30.                 printf("Can't open %s\n", g_strBmpPath);
  31.                 return;
  32.         }
  33.        
  34.         // 申请一块内存空间,并将其清零
  35.         hMem = GUI_ALLOC_AllocZero(file.obj.objsize); // 消耗25.2KB
  36.         if (!hMem)
  37.         {
  38.                 printf("GUI_ALLOC_AllocZero error\n");
  39.                 return;
  40.         }
  41.        
  42.         // 将申请到的内存的句柄转为指针类型
  43.         _acBuffer = GUI_ALLOC_h2p(hMem);
  44.        
  45.         res = f_read(&file, _acBuffer, file.obj.objsize, &br);
  46.         if (res != FR_OK)
  47.         {
  48.                 printf("Read file error!\n");
  49.                 GUI_ALLOC_Free(hMem);
  50.                 return;
  51.         }
  52.        
  53.         GUI_JPEG_GetInfo(_acBuffer, file.obj.objsize, &JpegInfo);
  54.        
  55.         hMemJPEG = GUI_MEMDEV_CreateEx(0, 0, JpegInfo.XSize, JpegInfo.YSize, GUI_MEMDEV_HASTRANS); // 消耗40KB
  56.         printf("hMemJPEG = %d\n", hMemJPEG);
  57.         GUI_MEMDEV_Select(hMemJPEG);
  58.         GUI_JPEG_Draw(_acBuffer, file.obj.objsize, 0, 0); // 内存不足,解码失败
  59.         GUI_MEMDEV_Select(0);
  60.        
  61.         GUI_ALLOC_Free(hMem);
  62.        
  63.         f_close(&file);
  64.        
  65.         GUI_MEMDEV_WriteAt(hMemJPEG, 0, 0);
  66.        
  67.         GUI_MEMDEV_Delete(hMemJPEG);
  68. }
复制代码



回复

使用道具 举报

12

主题

16

回帖

52

积分

初级会员

积分
52
 楼主| 发表于 2018-6-6 10:18:00 | 显示全部楼层
  1. static const char g_strJpgPath[] = "0:/jpg/armenia.jpg"; // 可以显示,320 * 240
  2. static const char g_strJpgPath1[] = "0:/jpg/earth.jpg";  // 可以显示,220 * 176
  3. static const char g_strJpgPath2[] = "0:/jpg/horse.jpg";  // 无法显示,160 * 128
复制代码
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117635
QQ
发表于 2018-6-6 10:50:38 | 显示全部楼层
其实动态内存小的话,奇怪的问题比较多,分析起来也不方便。你前面的文字分析可以的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-19 19:24 , Processed in 0.053491 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表