从零开始用C语言实现图片解码播放器(有源码)
Posted 正在起飞的蜗牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从零开始用C语言实现图片解码播放器(有源码)相关的知识,希望对你有一定的参考价值。
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、项目代码目录结构介绍
.
├── 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、应用层操作屏幕的代码
//表示一个屏幕设备
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 = %ld\\n", 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、代码修改
// 屏幕的设备节点
#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语言实现图片解码播放器(有源码)的主要内容,如果未能解决你的问题,请参考以下文章