文章目录

  • 链接
  • 扩展项目一
    • 1.目标
    • 2.分析
    • 3.实现
    • 4.效果
  • 扩展项目二
    • 1.目标
    • 2.分析
    • 3.实现
      • a.分配注册子类结构体
      • b.判断文件是否为png
      • c.获取png文件格式
    • 4.效果

链接

  1. JZ2440 数码相框项目 扩展项目介绍
  2. JZ2440 数码相框项目 扩展项目(三) 支持鼠标
  3. JZ2440 数码相框项目 扩展项目(四) 加快显示速度
  4. JZ2440 实现截图 保存为png格式
  5. 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相关推荐

  1. JZ2440 数码相框项目 扩展项目介绍

    文章目录 链接 背景 项目介绍 1. 环境 2. 注意事项 链接 JZ2440 数码相框项目 扩展项目(一) 多文件图标 (二) 显示png JZ2440 数码相框项目 扩展项目(三) 支持鼠标 JZ ...

  2. TortoiseSvn文件夹及文件图标不显示

    背景 其实一开始,我并不想以TortoiseSvn文件夹及文件图标不显示作为文章的标题,而是以TortoiseSvn右键弹出菜单不全作为标题.因为最开始我发现对eclipse从svn检出的项目右键操作 ...

  3. TortoiseGit文件夹及文件图标不显示解决方法

    一. 修复TortoiseGit文件夹和文件图标不显示 按Win+R键打开运行对话框,输入 regedit ,打开注册表: 找到 HKEY_LOCAL_MACHINE\Software\Microso ...

  4. 修复TortoiseGit文件夹和文件图标不显示

    之前在公司,使用vscode.IDEA等都是直接用自带的git插件,后来被大佬嘲笑怎么还用命令行,然后就随着大佬入坑了小乌龟TortoiseGit,别说,真香. 但是我在使用过程中,我的文件夹前面的图 ...

  5. 桌面html文件图标异常,.htm.html文件图标无法显示的解决办法

    .htm.html文件图标无法显示的解决办法 症状:后缀为Htm和Html的文件图标显示为未关联的.应用程序图标,并且通过常用的设置文件夹属性的方式修改不起作用,右键属性里改变默认打开程序也不起作用. ...

  6. WIN7 x64系统下TortoiseSVN文件夹及文件图标不显示解决方法

    WIN7 x64系统下TortoiseSVN文件夹及文件图标不显示解决方法 输入:win+R,输入regedit,调出注册表信息,按下Ctrl+F,在注册表里搜索"ShellIconOver ...

  7. MATLAB安装后的DOS框出现、脚本文件图标不显示、启动路径修改等问题解决

    MATLAB安装后的DOS框出现.脚本文件图标不显示.启动路径修改等问题解决 MATLAB安装方法 DOS框一闪而过问题 DOS框一闪而过问题说明 DOS框一闪而过问题解决 脚本文件图标异常问题 MA ...

  8. 修复电脑图片文件图标不显示的方法

    最近魅力网络安装了爱奇艺,发现爱奇艺自动安装了个万能播放器,打开图片也是用那个打开的,默认关联了图片文件,后来卸载了爱奇艺,发现图片文件的图标不显示了,看着很是不舒服为此只有手工更改了. 方法如下:我 ...

  9. 让element-ui的el-upload组件文件列表中文件图标自定义显示

    网上找了一堆都没有什么头绪, 其中有在上传文件过程中修改class达到突变更换的目的,但是引入了多文件和多组件的复杂场景后效果不尽人意, 比如删除文件或者回显没有办法正常显示图标了. 在研究了下, 因 ...

最新文章

  1. python电脑下载方法-python 获取机器snpython下载文件的几种常用方法
  2. python 字符串join
  3. 初学Java开发,有哪些从业方向可以选择?
  4. win7映射linux硬盘_win7下安装Linux实现双系统全攻略
  5. 为了你,我一定要写诗
  6. mybatis动态sql中的where标签的使用
  7. 武汉大学信息管理学院java上机考试_java上机试题
  8. python opencv3 特征提取与描述 DoG SIFT hessian surf
  9. 为什么JavaScript中给变量赋值会影响到其他地方?
  10. 大华NVR接入海康摄像机的设置
  11. Cadence输出Gerber文件
  12. 路由器刷机教程图解_小米路由器刷机教程
  13. Java-springboot生鲜电商项目(四)商品模块
  14. 【路由协议】和【应用协议】
  15. C语言报错:a label can only be part of a statement and a declaration is not a statement
  16. python面向对象程序设计董付国ppt_(董付国)Python 学习笔记---Python面向对象程序设计(1)...
  17. 可导区间中的唯一驻点一定是极值点吗?
  18. python浮点数多少位_python 浮点数保留几位小数
  19. itext html转换为pdf排版错乱,使用iText库将html转换为pdf时不适用hr的Inline CSS
  20. 力扣765——情侣牵手(贪心+BFS)

热门文章

  1. 优质的B2B撮合管理系统:如何帮助MRO工业品企业提升竞争力
  2. js jq 删除列表元素
  3. 如何测试重签名的应用功能是否正常
  4. 国内SLAM技术发展现状大解析
  5. 程序员解决失眠的方法,分享7个实用Tips
  6. TCP协议之三次握手四次挥手
  7. 学习python多久可以去找工作
  8. DAMA认证(CDGA/CDGP)证书好考吗
  9. 推荐经常会用到的几款SEO优化工具—竹晨网络
  10. ubuntu 开机黑屏 解决方案 之一(filesystem readonly)