赞
踩
在"browse页面"里, 对不同后缀名的文件使用不同的图标
该目标比较简单,只需要修改现有"browse页面"里用于显示文件图标的代码,这里可以发现在源码包用于显示文件图标的图片文件为"file.bmp",在代码中搜索该字符串就很容易修改。
搜索得到该代码:
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; // 后缀不同,返回默认图标
}
没有去找 bmp图片,手绘。(png格式是之后扩展的,只需要在数组中增加一行)
支持其他格式的图片文件, 比如png
由于 picfmt_manager.c 图像格式管理抽象类已经做好了抽象,只需要仿照其他子类写出符合该抽象类的子类就可以了,难点主要在于解析png图像。
使用 libpng 库
下载后可以按照源码中的 example.c 来仿写。
在 render/format 文件夹下添加 png.c 文件,修改 Makefile。
typedef struct PicFileParser { // 抽象类结构体定义在 pic_operation.h char *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 修改出来的:
返回值: 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));
}
// 成功返回 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 方法来捕获库函数中错误,后三个参数填 NULL png_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 method if (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 signature png_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_end png_destroy_read_struct(&png_ptr, &info_ptr, NULL); // 销毁对象 return 0; // 成功读取 }
据说都用该图片测试效果,我也试试。
了解更多:lenna的故事
下载原图:lenna原图
保存的话好像是jpg格式558K,我用画图转换成png格式,大小居然有5.53M
在JZ2440中打开很慢,至少要 6、7秒左右。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。