1、项目描述
1.1、项目硬件平台介绍
(1)硬件平台:九鼎公司的X210开发板,S5PV210(Cortex-A8内核);
(2)软件平台:linux2.6.35.7内核,直接基于linux API操作
1.2、项目功能介绍
(1)调用编译好的可执行程序时传入图片的存放路径,程序会自动将路径里的图片显示在屏幕上;
(2)程序会自动检索图片路径下包括子目录在内的所有图片文件;
(3)支持的文件格式包括BMP(8bit、16bit、24bit、32bit)、JPG、PNG;
(4)支持触摸屏翻页功能,点击左侧屏幕则向前翻页,点击右侧屏幕可向后翻页,支持循环翻页;
1.3、项目涉及到的技术
(1)C语言和linux基础操作;
(2)通用Makefile管理工程的相关知识;
(3)应用层操作屏幕的代码分析;
(4)bmp、jpg、png格式解码库的移植;
(5)应用层操作触摸屏的代码分析;
(6)linux中递归遍历文件夹内容的操作;
(7)动态库的编译和移植;
(8)实际项目中目录结构的分析;
2、项目代码目录结构介绍
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26. ├── bin ——存放生成的可执行程序 ├── build ——Makefile编译脚本 ├── doc ——项目说明文档 ├── image ——存放要播放的图片 │ ├── bmp │ ├── jpg │ └── png ├── include ——相关头文件 │ ├── common ——公共的配置头文件 │ ├── decode ——图片解码相关的头文件 │ │ ├── bmp │ │ ├── jpg │ │ ├── png │ │ │ └── libpng16 │ │ └── zlib │ ├── fb ——屏幕显示相关头文件 │ ├── imageManager ——图片管理头文件 │ └── touchScreen ——触摸屏管理头文件 ├── lib ——依赖的动态库 └── src ——源码目录 ├── decode ——图片解码相关源码 ├── fb ——屏幕显示相关源码 ├── imageManager ——图片管理相关源码 └── touchScreen ——触摸屏相关源码
参考博客:《实际工作开发中C语言工程的目录结构分析》;
3、Makefile介绍
项目管理使用的通用Makefile模板,具体参考博客:《项目通用Makefile的编写(包含Makefile.build文件分析)》;
4、屏幕显示模块
4.1、屏幕驱动的移植
《嵌入式开发(S5PV210)——LCD显示器》
《Linux 帧缓冲子系统详解:LCD介绍、framebuffer驱动框架、LCD驱动源码分析》
《LCD驱动源码分析(s3cfb.c)》
4.2、应用层操作屏幕的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117//表示一个屏幕设备 typedef struct { unsigned int *pfb; // pfb指向framebuffer内存地址首地址 int fp; // 打开设备节点得到的文件描述符 int width; //屏幕的实际宽 int height; //屏幕的实际高 int virWidth; //屏幕的虚拟宽 int virHeight; //屏幕的虚拟高 int bpp; //每个像素占用的位数 }fbHandle; // 结构体用来封装一个图片的各种信息 typedef struct pic_info { char *pathname; // 图片在文件系统中的路径名+文件名 unsigned int width; // 图片分辨率之宽 unsigned int height; // 图片分辨率之高 unsigned int bpp; // 图片bpp char *pData; // 指向图片有效数据存储的buf数据 }pic_info; //传入屏幕的设备节点路径,返回屏幕的设备信息 fbHandle *fb_open(char* devPath) { int ret = -1; fbHandle *fbDev = NULL; struct fb_fix_screeninfo finfo; struct fb_var_screeninfo vinfo; fbDev = malloc(sizeof(fbHandle)); memset(fbDev, 0, sizeof(fbHandle)); // 第1步:打开设备 fbDev->fp = -1; fbDev->fp = open(devPath, O_RDWR); if (fbDev->fp < 0) { perror("open error"); goto fail; } debug("open %s success.n", devPath); // 第2步:获取设备的硬件信息 ret = ioctl(fbDev->fp, FBIOGET_FSCREENINFO, &finfo); if (ret < 0) { perror("ioctl"); goto fail; } debug("smem_start = 0x%lx, smem_len = %u.n", finfo.smem_start, finfo.smem_len); ret = ioctl(fbDev->fp, FBIOGET_VSCREENINFO, &vinfo); if (ret < 0) { perror("ioctl"); goto fail; } debug("xres = %u, yres = %u.n", vinfo.xres, vinfo.yres); debug("xres_virtual = %u, yres_virtual = %u.n", vinfo.xres_virtual, vinfo.yres_virtual); debug("bpp = %u.n", vinfo.bits_per_pixel); fbDev->width = vinfo.xres; fbDev->height = vinfo.yres; fbDev->virWidth = vinfo.xres_virtual; fbDev->virHeight = vinfo.yres_virtual; fbDev->bpp = vinfo.bits_per_pixel; // 第3步:进行mmap unsigned long len = vinfo.xres_virtual * vinfo.yres_virtual * vinfo.bits_per_pixel / 8; debug("len = %ldn", len); fbDev->pfb = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fbDev->fp, 0); if (NULL == fbDev->pfb) { perror("mmap error"); goto fail; } debug("pfb = %p.n", fbDev->pfb); return fbDev; fail: if(fbDev->fp >= 0) { close(fbDev->fp); } free(fbDev); return NULL; } //往屏幕显示图片 void fb_draw_rgb(fbHandle *fbDev, const struct pic_info *pPic) { const char *pData = (const char *)pPic->pData; // 指针指向图像数组 unsigned int cnt = 0, a = 0; unsigned int x, y; a = 0; for (y = 0; y < pPic->height; y++) { for (x=0; x<pPic->width; x++) { //cnt表示当前像素点的编号 cnt = fbDev->width * y + x; // 当前像素点的数据 *(fbDev->pfb + cnt) = ((pData[a+2]<<0) | (pData[a+1]<<8)| (pData[a+0]<<16)); a += 3; } } }
参考博客:《应用程序操作LCD源码分析》;
5、图片解码模块
(1)bmp图片解码函数编写,参考博客:《C语言实现BMP格式转RGB格式、YUV格式》、《C语言实现RGB888转BMP格式图片功能》;
(2)jpg解码库移植,参考博客:《jpg解码库移植过程详解》;
(2)png解码库移植,参考博客:《png格式解码库移植过程详解》;
6、图片管理模块
(1)调用linux系统的文件夹操作的API,比如opendir、 readdir、lstat等函数去遍历文件夹下的所有文件;
(2)判断读取到的文件,如果是bmp、jpg、png图片则添加到数组中管理起来,后续在播放图片时会用到;
7、触摸屏模块
(1)通过操作触摸屏的设备节点来读取坐标信息,通过判断坐标来决定是向前翻页还是向后翻页;
(2)《嵌入式开发(S5PV210)——ADC和触摸屏》、《gslx680触摸屏驱动源码码分析(gslX680.c)》、《linux输入子系统详解——看这一篇就够了》
8、项目代码移植
8.1、硬件平台要求
(1)开发板必须有显示屏和触摸屏,并且显示屏和触摸屏的驱动移植正确,可以正常功能;
(2)在移植代码前,先通过设备节点,确认显示屏和触摸屏工作正常;
8.2、代码修改
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// 屏幕的设备节点 #define FBDEVICE "/dev/fb0" # 支持的图片最大的分辨率 #define PICTURE_BUFFER_MAX_SIZE (1920 * 1080 * 3 ) // 最多支持的图片数目 #define MAX_IMAGE_CNT 100 // 触摸屏设备的设备名 #define DEVICE_TOUCHSCREEN "/dev/input/event2" // 定义触摸翻页区域的宽度 #define TOUCH_WIDTH 200
(1)修改主Makefile中的交叉编译工具链为自己平台的(CROSS_COMPILE);
(2)上面的配置都在config.h文件中,需要根据自己开发板的情况去修改,特别是屏幕和触摸屏的设备节点名称必须正确;
8.3、源码获取
《图片解码播放器源码下载》
9、参考资料
《朱友鹏——核心课程》
最后
以上就是碧蓝小甜瓜最近收集整理的关于从零开始用C语言实现图片解码播放器(有源码)1、项目描述2、项目代码目录结构介绍3、Makefile介绍4、屏幕显示模块5、图片解码模块6、图片管理模块7、触摸屏模块8、项目代码移植9、参考资料的全部内容,更多相关从零开始用C语言实现图片解码播放器(有源码)1、项目描述2、项目代码目录结构介绍3、Makefile介绍4、屏幕显示模块5、图片解码模块6、图片管理模块7、触摸屏模块8、项目代码移植9、参考资料内容请搜索靠谱客的其他文章。
发表评论 取消回复