当前位置:   article > 正文

数码相册项目_基于s5p6818的数码相册设计的摘要部分

基于s5p6818的数码相册设计的摘要部分

一、设计目标:

        开发一个类似相册的应用程序,利用开发板的液晶屏和触摸屏,支持用户友好界面、多种图片格式,并提供方便浏览照片的功能。

二、功能描述:

  1. 支持滑动浏览图片:用户可以通过触摸屏滑动操作,在指定目录下浏览图片。

  2. 支持幻灯片播放:提供幻灯片播放功能,用户可以选择自动播放图片。

  3. 解析图片格式:应用程序智能调用相关的库,对支持的图片格式(如JPG和BMP)进行解析显示。

  4. 目录文件过滤:应用程序支持指定目录下的文件过滤,以获取所有符合条件的图片文件。

  5. 图片自动居中:应用程序会自动将图片在屏幕上居中显示,确保用户可以完整地看到图片内容。

  6. 图片自适应屏幕尺寸:应用程序会自动缩放大图,以适应屏幕尺寸,保证图片显示效果。

  7. 双缓冲机制:为了优化画面显示效果,应用程序采用双缓冲机制,避免闪屏现象。

  8. 功能选择:提供一个功能选择页面,用户可以选择浏览照片、幻灯片播放或其他功能。

三、设计方案:

  1. 硬件方面:使用开发板的液晶屏和触摸屏来显示图片,并支持滑动操作。

  2. 数据结构:采用内核双向链表来保存目录下的文件信息,包括文件名、路径等。通过遍历链表来实现图片的显示和滑动操作。

  3. 用户界面设计:设计一个用户友好的界面,通过触摸屏进行交互操作。

  4. 功能实现:根据用户操作,调用相应的功能模块,如图片显示模块、幻灯片播放模块等。

  5. 动态库加载:根据图片格式,动态加载相应的库进行解析和显示。

  6. 目录检索和文件过滤:使用文件系统相关的API,遍历指定目录,筛选出符合条件的图片文件。

四、系统框架

  1. 用户界面层:
    1. 主页:显示电子相册的主界面,提供功能选择入口。
    2. 浏览界面:展示图片,支持滑动操作和幻灯片播放。
  2. 应用逻辑层:
    1. 图片管理模块:负责管理图片数据和文件信息,包括读取目录、文件过滤、链表存储等。
    2. 图片显示模块:负责显示图片,支持居中和自适应屏幕尺寸。
    3. 幻灯片播放模块:实现幻灯片自动播放功能,包括时间间隔控制和图片切换。
    4. 功能选择模块:处理用户选择的功能,根据不同选项调用相应模块。
  3. 库调用层:
    1. 图片解析库:根据图片格式动态加载相应的库文件,解析并显示图片。
    2. 文件系统库:提供文件操作接口,用于目录遍历和文件过滤。
  4. 硬件驱动层:
    1. LCD驱动:控制液晶屏的显示。
    2. 触摸屏驱动:处理用户触摸输入。
  5. 系统核心层:
    1. 操作系统:提供系统资源管理和任务调度功能。
    2. 设备驱动:与硬件驱动层配合,实现对硬件设备的操作。

五、实现过程

  1. 初始化lcd
    1. void lcd_init(struct lcd_info *p)
    2. {
    3. p->lcd = open("/dev/fb0",O_RDWR);
    4. if(p->lcd == -1)
    5. {
    6. perror("打开lcd失败");
    7. return;
    8. }
    9. // 准备好lcd设备(如果多次显示,应该只做一遍)
    10. static bool initialized = false;
    11. if(initialized)
    12. {
    13. return;
    14. }
    15. // 获取硬件参数
    16. ioctl(p->lcd,FBIOGET_VSCREENINFO,&finfo);
    17. p->width = finfo.xres;
    18. p->height = finfo.yres;
    19. p->bpp = finfo.bits_per_pixel;
    20. p->screen_size = p->width * p->height * p->bpp/8;
    21. // 映射内存
    22. p->fmb = mmap(NULL,p->screen_size*2,PROT_READ|PROT_WRITE,MAP_SHARED,p->lcd,0);
    23. if(p->fmb == MAP_FAILED)
    24. {
    25. perror("内存映射失败");
    26. exit(0);
    27. }
    28. //将映射的内存块清零
    29. bzero(p->fmb,p->screen_size);
    30. initialized = true;
    31. }

  2.  初始化内核链表
    1. struct photo *init_list()
    2. {
    3. struct photo *head = calloc(1, sizeof(struct photo));
    4. if(head != NULL)
    5. {
    6. INIT_LIST_HEAD(&head->list);
    7. }
    8. return head;
    9. }

  3.  对目录进行操作文件过滤
    1. // 打开目录获得目录指针
    2. DIR *dp = opendir(argv[1]);
    3. if(argc != 2)
    4. {
    5. fprintf(stderr,"请指定一个目录\n");
    6. exit(0);
    7. }
    8. // 获得当前进程所在路径
    9. char path[100];
    10. bzero(path,100);
    11. printf("当前路径: %s\n",getcwd(path,100));
    12. // 进入目录
    13. chdir(dirent_path);
    14. // 目录项结构体
    15. struct dirent *ep;
    16. while (1)
    17. {
    18. // 读取目录项
    19. ep = readdir(dp);
    20. if(ep == NULL)
    21. {
    22. printf("读完了\n");
    23. break;
    24. }
    25. // 跳过以‘.’开头的文件
    26. if(ep->d_name[0] == '.')
    27. continue;
    28. // 过滤不是.jpg格式的文件名
    29. // DT_REG是普通文件类型
    30. if (ep->d_type == DT_REG && ((strstr(ep->d_name, ".jpg") !=NULL) || (strstr(ep->d_name, ".bmp")!= NULL)))
    31. {
    32. struct photo *p = new_node(ep->d_name);
    33. list_add_tail(&p->list,&head->list);
    34. }
    35. }

  4.  读取触摸屏数据并判定滑动方向
    1. int fd = open("/dev/input/event0",O_RDWR);
    2. if(fd == 0)
    3. {
    4. perror("打开触摸屏失败\n");
    5. return -1;
    6. }
    7. struct input_event ev;
    8. int ret;
    9. int flag = 0;
    10. int count = 0;
    11. while(1)
    12. {
    13. // 读取触摸屏数据
    14. ret = read(fd,&ev,sizeof(ev));
    15. if(ret != sizeof(ev))
    16. {
    17. close(fd);
    18. perror("读取失败");
    19. return -1;
    20. }
    21. // 判断触摸事件,并获取x值
    22. if(ev.type == EV_ABS && ev.code == ABS_X)
    23. {
    24. if(p1.x < 0)
    25. {
    26. p1.x = ev.value;
    27. }
    28. else
    29. {
    30. p2.x = ev.value;
    31. }
    32. }
    33. if(ev.type == EV_ABS && ev.code == ABS_Y)
    34. {
    35. if(p1.y < 0)
    36. {
    37. p1.y = ev.value;
    38. }
    39. else
    40. {
    41. p2.y = ev.value;
    42. }
    43. }
    44. // 最后读取到的数据与第一次读取到的数据相比较
    45. // 判断滑动的方向
    46. if(ev.type == EV_KEY && ev.code == BTN_TOUCH && ev.value == 0)
    47. {
    48. int dt_x = abs(p1.x - p2.x);
    49. int dt_y = abs(p1.y - p2.y);
    50. if(dt_x > 2*dt_y)
    51. {
    52. if(p1.x > p2.x)
    53. return left;
    54. if(p1.x < p2.x)
    55. return right;
    56. }else if(2*dt_x < dt_y)
    57. {
    58. if(p1.y > p2.y)
    59. return up;
    60. if(p1.y < p2.y)
    61. return down;
    62. }
    63. else // 单击不滑屏
    64. {
    65. p1.x = -1;
    66. p1.y = -1;
    67. p2.x = -1;
    68. p2.y = -1;
    69. }
    70. }
    71. }

  5.  根据图片文件名字选择加载哪个类型的动态库
    1. p = list_entry(pos,struct photo,list);
    2. //打开指定的动态库,并找到显示图片的函数指针
    3. void *handle;
    4. if(strstr(p->name,".jpg"))
    5. {
    6. handle = dlopen("libjpg.so",RTLD_NOW);
    7. printf("%d\n",__LINE__);
    8. }
    9. else if(strstr(p->name,".bmp"))
    10. {
    11. handle = dlopen("libbmp.so",RTLD_NOW);
    12. printf("%d\n",__LINE__);
    13. }
    14. if(handle == NULL)
    15. {
    16. fprintf(stderr,"打开动态库失败:%s\n",dlerror());
    17. exit(0);
    18. }
    19. void (*show_img)(const char *jpgFile, struct lcd_info *p);
    20. show_img = dlsym(handle,"show_img");
    21. if(show_img == NULL)
    22. {
    23. fprintf(stderr,"dlsym()失败:%s\n",dlerror());
    24. exit(0);
    25. }

  6.  对滑动后做出响应,显示相应的图片
    1. switch(x)
    2. {
    3. case left:
    4. if(pos->prev != &head->list)
    5. {
    6. pos = pos->prev;
    7. printf("向左滑动,前一张\n");
    8. }
    9. else
    10. {
    11. printf("最后一张啦,从头开始滑\n");
    12. pos = head->list.prev;
    13. }
    14. break;
    15. case right:
    16. if(pos->next != &head->list)
    17. {
    18. printf("向右滑动,下一张\n");
    19. pos = pos->next;
    20. }
    21. else
    22. {
    23. printf("滑到头啦,重新开始\n");
    24. pos = head->list.next;
    25. }
    26. break;
    27. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/855515
推荐阅读
相关标签
  

闽ICP备14008679号