JZ2440 数码相框项目 扩展项目(一) 多文件图标 (二) 显示png
文章目录
- 链接
- 扩展项目一
- 1.目标
- 2.分析
- 3.实现
- 4.效果
- 扩展项目二
- 1.目标
- 2.分析
- 3.实现
- a.分配注册子类结构体
- b.判断文件是否为png
- c.获取png文件格式
- 4.效果
链接
- JZ2440 数码相框项目 扩展项目介绍
- JZ2440 数码相框项目 扩展项目(三) 支持鼠标
- JZ2440 数码相框项目 扩展项目(四) 加快显示速度
- JZ2440 实现截图 保存为png格式
- JZ2440 数码相框项目 扩展项目 1-4 源码下载
扩展项目一
1.目标
在"browse页面"里, 对不同后缀名的文件使用不同的图标
2.分析
该目标比较简单,只需要修改现有"browse页面"里用于显示文件图标的代码,这里可以发现在源码包用于显示文件图标的图片文件为"file.bmp",在代码中搜索该字符串就很容易修改。
3.实现
搜索得到该代码:
static char *g_strFileIconName = "file.bmp";
static T_PixelDatas g_tFileIconPixelDatas; //
修改该变量所有使用 “g_tFileIconPixelDatas” 的位置,改成所支持的文件格式的数组即可,
重新定义声明如下:
#define ARRAYSIZE(array) (sizeof(array)/sizeof(array[0]))typedef struct FileIconDesc {const char * type; // 支持的文件类型const char * file; // 文件类型对应的图标文件T_PixelDatas tPixeldatas; // 从图标文件中读取的RGB数据,在pic_operation.h中定义
}T_FileIconDesc, *PT_FileIconDesc;#define FileIconDescItem(__type, __file) \
{\.type = __type , \.file = __file , \
}// 每次扩展只需要增加一行
static T_FileIconDesc g_TfileIconDesc[] = {FileIconDescItem(".bmp", "ico_bmp.bmp"),FileIconDescItem(".c", "ico_c.bmp"),FileIconDescItem(".h", "ico_h.bmp"),FileIconDescItem(".jpg", "ico_jpg.bmp"),FileIconDescItem(".txt", "ico_txt.bmp"),
};
#define UNKNOW_FILETYPE_ICON "ico_unknow.bmp" // 其余不支持的文件类型的图标文件
static T_PixelDatas g_tFileIconPixelDatas; // 该变量用来存放不支持文件类型图标RGB数据
修改定义后,修改文件中其余使用 g_strFileIconName 变量的地方,在原来读取图标数据的地方初始化新定义的图标数组的 tPixeldatas 成员。(当然别忘了初始化不支持的文件类型的图标文件)
使用该函数来获取图标数据(根据后缀名判断)
static PT_PixelDatas GetFilePixelData(const char * filename) {int i, len;for(i = 0;i < ARRAYSIZE(g_TfileIconDesc);i++) {len = strlen(filename) - strlen(g_TfileIconDesc[i].type);if (len >= 0 && 0 == strcmp(filename + len, g_TfileIconDesc[i].type)) {return &g_TfileIconDesc[i].tPixeldatas; // 后缀相同,返回图标数据}}return &g_tFileIconPixelDatas; // 后缀不同,返回默认图标
}
4.效果
没有去找 bmp图片,手绘。(png格式是之后扩展的,只需要在数组中增加一行)
扩展项目二
1.目标
支持其他格式的图片文件, 比如png
2.分析
由于 picfmt_manager.c 图像格式管理抽象类已经做好了抽象,只需要仿照其他子类写出符合该抽象类的子类就可以了,难点主要在于解析png图像。
使用 libpng 库
下载后可以按照源码中的 example.c 来仿写。
3.实现
在 render/format 文件夹下添加 png.c 文件,修改 Makefile。
a.分配注册子类结构体
typedef struct PicFileParser { // 抽象类结构体定义在 pic_operation.hchar *name; /* 图片文件解析模块的名字 */int (*isSupport)(PT_FileMap ptFileMap); /* 是否支持某文件 */int (*GetPixelDatas)(PT_FileMap ptFileMap, PT_PixelDatas ptPixelDatas); /* 从文件中解析出图像的象素数据 */int (*FreePixelDatas)(PT_PixelDatas ptPixelDatas); /* 释放图像的象素数据所占内存 */struct PicFileParser *ptNext; /* 链表 */
}T_PicFileParser, *PT_PicFileParser;//========= 分配注册子类结构体 =================================================
static T_PicFileParser g_tPNGParser = {.name = "png",.isSupport = isPNGFormat, // 判断文件是否为png格式文件.GetPixelDatas = GetPixelDatasFrmPNG, // 获取png文件的数据,应保持接口一致.FreePixelDatas = FreePixelDatasForPNG, // 销毁对象,清理内存
};int PNGParserInit(void) {return RegisterPicFileParser(&g_tPNGParser);
}
以下函数都是根据 example.c 修改出来的:
b.判断文件是否为png
返回值: 0 代表不是png, 非0 代表是png
#define PNG_BYTES_TO_CHECK 4
static int isPNGFormat(PT_FileMap ptFileMap) // 该结构体定义在 file.h 已经open的文件
{char buf[PNG_BYTES_TO_CHECK];if (fseek(ptFileMap->tFp, 0, SEEK_SET)) // 必须读取文件的头return 0;/* Read in some of the signature bytes. */ // 读取文件头if (fread(buf, 1, PNG_BYTES_TO_CHECK, ptFileMap->tFp) != PNG_BYTES_TO_CHECK)return 0;/* Compare the first PNG_BYTES_TO_CHECK bytes of the signature.* Return nonzero (true) if they match. */ // 调用 libpng 库函数return (!png_sig_cmp((png_const_bytep)buf, 0, PNG_BYTES_TO_CHECK));
}
c.获取png文件格式
// 成功返回 0 , 失败返回 非0 // 已经打开的png文件 // 返回给调用者的RGB图像数据
static int GetPixelDatasFrmPNG(PT_FileMap ptFileMap, PT_PixelDatas ptPixelDatas)
{png_structp png_ptr;png_infop info_ptr;png_uint_32 width, height;int bit_depth, color_type, interlace_type;int row;fseek(ptFileMap->tFp, 0, SEEK_SET); // 保证从文件头部开始读取// If you want to use the default stderr and longjump method, you can supply NULL for the last three parameters.// 创建 png 对象,使用 longjump 方法来捕获库函数中错误,后三个参数填 NULLpng_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);if (png_ptr == NULL) { return -1; // 恭喜你,没有对象,单身狗一枚}/* Allocate/initialize the memory for image information. REQUIRED. */info_ptr = png_create_info_struct(png_ptr);if (info_ptr == NULL) {png_destroy_read_struct(&png_ptr, NULL, NULL);return -1; // 恭喜你,逃不过单身狗的命运}// Set error handling if you are using the setjmp/longjmp methodif (setjmp(png_jmpbuf(png_ptr))) // 使用 longjmp 方法{/* Free all of the memory associated with the png_ptr and info_ptr. */png_destroy_read_struct(&png_ptr, &info_ptr, NULL);free(ptPixelDatas->aucPixelDatas);/* If we get here, we had a problem reading the file. */return -1;}png_init_io(png_ptr, ptFileMap->tFp); // 初始化对象// If we have already read some of the signaturepng_set_sig_bytes(png_ptr, 0); // 不懂就写 0 ,可能是说读取了多少字节了?png_read_info(png_ptr, info_ptr); // 读取 png 文件头中的信息png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,&interlace_type, NULL, NULL); // 获取 png 文件头中的信息DBG_PRINTF("\twidth=%d,height=%d,bit_depth=%d\n\tcolor_type=%d,interlace_type=%d\n",width, height, bit_depth, color_type, interlace_type);// Strip alpha bytes from the input data without combining with the background (not recommended).png_set_strip_alpha(png_ptr); // 丢弃透明度和背景/* Expand paletted colors into true RGB triplets. */if (color_type == PNG_COLOR_TYPE_PALETTE)png_set_palette_to_rgb(png_ptr); // 如果是调色板颜色,转换成 RGB 颜色/* Invert monochrome files to have 0 as white and 1 as black. *///png_set_invert_mono(png_ptr); // 单色文件反转(没有使用),彩色会不会反转我也没有测试过png_read_update_info(png_ptr, info_ptr); // 似乎是更新上面的配置png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,&interlace_type, NULL, NULL); // 再读取一次,会发现 color_type 的值可能不一样DBG_PRINTF("\twidth=%d,height=%d,bit_depth=%d\n\tcolor_type=%d,interlace_type=%d\n",width, height, bit_depth, color_type, interlace_type);// 准备数据输出给调用者ptPixelDatas->iWidth = width;ptPixelDatas->iHeight = height;//ptPixelDatas->iBpp = 24; // 该变量被抽象类设置ptPixelDatas->iLineBytes = width * (ptPixelDatas->iBpp >> 3);ptPixelDatas->iTotalBytes = height * ptPixelDatas->iLineBytes;ptPixelDatas->aucPixelDatas = (unsigned char*)malloc(ptPixelDatas->iTotalBytes);printf("ptPixelDatas->iTotalBytes = %d\n",ptPixelDatas->iTotalBytes);if(!ptPixelDatas->aucPixelDatas) {DBG_PRINTF("%s malloc error!\n",ptFileMap->strFileName);return -1;}unsigned char* tmpbuf = (unsigned char*)malloc(width * height * 3);if(!tmpbuf) {free(ptPixelDatas->aucPixelDatas);return -1;}for (row = 0; row < height; row++){png_read_row(png_ptr, tmpbuf, NULL); // 读取一行数据,读取的数据为24BPP,RGB// 该函数将读取到的一行数据转换为显示器所需要的BPP数据,这里不介绍CovertOneLine(width, 24, ptPixelDatas->iBpp, tmpbuf,ptPixelDatas->aucPixelDatas + row * ptPixelDatas->iLineBytes);}free(tmpbuf);png_read_end(png_ptr, info_ptr); // 读取结束调用 png_read_endpng_destroy_read_struct(&png_ptr, &info_ptr, NULL); // 销毁对象return 0; // 成功读取
}
4.效果
据说都用该图片测试效果,我也试试。
了解更多:lenna的故事
下载原图:lenna原图
保存的话好像是jpg格式558K,我用画图转换成png格式,大小居然有5.53M
在JZ2440中打开很慢,至少要 6、7秒左右。
JZ2440 数码相框项目 扩展项目(一) 多文件图标 (二) 显示png相关推荐
- JZ2440 数码相框项目 扩展项目介绍
文章目录 链接 背景 项目介绍 1. 环境 2. 注意事项 链接 JZ2440 数码相框项目 扩展项目(一) 多文件图标 (二) 显示png JZ2440 数码相框项目 扩展项目(三) 支持鼠标 JZ ...
- TortoiseSvn文件夹及文件图标不显示
背景 其实一开始,我并不想以TortoiseSvn文件夹及文件图标不显示作为文章的标题,而是以TortoiseSvn右键弹出菜单不全作为标题.因为最开始我发现对eclipse从svn检出的项目右键操作 ...
- TortoiseGit文件夹及文件图标不显示解决方法
一. 修复TortoiseGit文件夹和文件图标不显示 按Win+R键打开运行对话框,输入 regedit ,打开注册表: 找到 HKEY_LOCAL_MACHINE\Software\Microso ...
- 修复TortoiseGit文件夹和文件图标不显示
之前在公司,使用vscode.IDEA等都是直接用自带的git插件,后来被大佬嘲笑怎么还用命令行,然后就随着大佬入坑了小乌龟TortoiseGit,别说,真香. 但是我在使用过程中,我的文件夹前面的图 ...
- 桌面html文件图标异常,.htm.html文件图标无法显示的解决办法
.htm.html文件图标无法显示的解决办法 症状:后缀为Htm和Html的文件图标显示为未关联的.应用程序图标,并且通过常用的设置文件夹属性的方式修改不起作用,右键属性里改变默认打开程序也不起作用. ...
- WIN7 x64系统下TortoiseSVN文件夹及文件图标不显示解决方法
WIN7 x64系统下TortoiseSVN文件夹及文件图标不显示解决方法 输入:win+R,输入regedit,调出注册表信息,按下Ctrl+F,在注册表里搜索"ShellIconOver ...
- MATLAB安装后的DOS框出现、脚本文件图标不显示、启动路径修改等问题解决
MATLAB安装后的DOS框出现.脚本文件图标不显示.启动路径修改等问题解决 MATLAB安装方法 DOS框一闪而过问题 DOS框一闪而过问题说明 DOS框一闪而过问题解决 脚本文件图标异常问题 MA ...
- 修复电脑图片文件图标不显示的方法
最近魅力网络安装了爱奇艺,发现爱奇艺自动安装了个万能播放器,打开图片也是用那个打开的,默认关联了图片文件,后来卸载了爱奇艺,发现图片文件的图标不显示了,看着很是不舒服为此只有手工更改了. 方法如下:我 ...
- 让element-ui的el-upload组件文件列表中文件图标自定义显示
网上找了一堆都没有什么头绪, 其中有在上传文件过程中修改class达到突变更换的目的,但是引入了多文件和多组件的复杂场景后效果不尽人意, 比如删除文件或者回显没有办法正常显示图标了. 在研究了下, 因 ...
最新文章
- python电脑下载方法-python 获取机器snpython下载文件的几种常用方法
- python 字符串join
- 初学Java开发,有哪些从业方向可以选择?
- win7映射linux硬盘_win7下安装Linux实现双系统全攻略
- 为了你,我一定要写诗
- mybatis动态sql中的where标签的使用
- 武汉大学信息管理学院java上机考试_java上机试题
- python opencv3 特征提取与描述 DoG SIFT hessian surf
- 为什么JavaScript中给变量赋值会影响到其他地方?
- 大华NVR接入海康摄像机的设置
- Cadence输出Gerber文件
- 路由器刷机教程图解_小米路由器刷机教程
- Java-springboot生鲜电商项目(四)商品模块
- 【路由协议】和【应用协议】
- C语言报错:a label can only be part of a statement and a declaration is not a statement
- python面向对象程序设计董付国ppt_(董付国)Python 学习笔记---Python面向对象程序设计(1)...
- 可导区间中的唯一驻点一定是极值点吗?
- python浮点数多少位_python 浮点数保留几位小数
- itext html转换为pdf排版错乱,使用iText库将html转换为pdf时不适用hr的Inline CSS
- 力扣765——情侣牵手(贪心+BFS)