分类:
2009-05-16 18:42:02
程序范例 image.c 是以 hello.c 为基础,加上显示图片的功能。透过 image.c 我们可以学到以下的 Nano-X 程序设计方法:
˙ 如何使用嵌入式图片
˙ 如何将图片显示于窗口上
由档案读取图片文件并显示显示图片是一般常见的做法,这里我们所要实作的范例是希望可以将图片直接嵌入程序里,而不是由外部档案读取。
如何使用嵌入式图片
要将图片嵌入于程序里,首先必须将图片转换成数值数据形式的 C 程序。Nano-X 提供一个档名为 convbmp 的工具来将 BMP 格式的图片转换成 C 程序。
convbmp工具的原始程序位于 src/mwin/bmp/convbmp.c,这是提供给 Microwindows API 使用者的工具,因此我们在设定 Nano-X 编译选项时,除了勾选 Nano-X API 外,还要勾选 Microwindows API 选项才能产生 convbmp 执行文件。编译后可以在 src/bin/ 目录下找到 convbmp,我们手动将此工具安装到 /usr/bin/目录下,以方便我们使用:
# cd microwin-0.90/
# cp src/bin/convbmp /usr/bin
先将取得的图档转换成 BMP 的格式,再利用 convbmp 转换成 C 程序。例如,我想转换图档 jollen.bmp,那么将图文件转换成 C 程序的指令就是:
$ convbmp jollen.bmp
转换后便会得到 jollen.c。接着我们再修改 hello.c 将图片显示于窗口上。
如何将图片显示于窗口上
因为图片数据属于外部变量,因此先在程序里宣告外部图片变量:
extern GR_IMAGE_HDR image_jollen;
image_jollen 是一个数组,存放图文件的 pixel 数据,此数组由 convbmp 转换后产生,详见 jollen.c 程序。
jollen.c包含三个结构:第一个是关于颜色调色板的存储结构,包含了多达256种颜色,convbmp在这里面找到颜色和欲转换的图片匹配。第二个是关于图片bit位的存储数组。最后一个结构是一个public型的数组,名称为MWIMAGEHDR。本例中该数组命名为image_jollen,这是因为convbmp对转换后生成文件的命名规则是在原文件名前加上image_。本例使用的是jellen.bmp,所以该结构名为image_penguin。
接着,在处理 GR_EVENT_TYPE_EXPOSURE 事件的地方呼叫 GrDrawImageBits() 函数画出图片即可:
GrDrawImageBits(wid, gc, 0, 0, &image_jollen);
编译时别忘了与 jollen.c 程序做连结,这个部份可以写一个简单的 Makefile rule来完成:
mage: image.o jollen.o
$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
以下是 image.c 的完整程序,粗体字是新加入的程序代码。
/*
* Copyright(c) 2003,2004
*
* - Nano-X API example.
* - image.c
*/
#include
#define MWINCLUDECOLORS
#include
GR_WINDOW_ID wid;
GR_GC_ID gc;
/* 外部图片 */
extern GR_IMAGE_HDR image_jollen;
void event_handler (GR_EVENT *event);
int main (void)
{
if (GrOpen() < 0) {
fprintf (stderr, "GrOpen failed");
return -1;
}
gc = GrNewGC();
GrSetGCForeground (gc, 0xFF0000);
wid = GrNewWindowEx(GR_WM_PROPS_APPFRAME |
GR_WM_PROPS_CAPTION |
GR_WM_PROPS_CLOSEBOX,
"jollen.org",
GR_ROOT_WINDOW_ID,
0, 0,
image_jollen.width, /* 图片宽度 */ image_jollen.height /* 图片高度 */,
0xFFFFFF); GrSelectEvents(wid, GR_EVENT_MASK_CLOSE_REQ | GR_EVENT_MASK_EXPOSURE);
GrMapWindow(wid);
GrMainLoop(event_handler);
return 0;
}
void event_handler (GR_EVENT *event)
{
switch (event->type)
{
case GR_EVENT_TYPE_EXPOSURE:
GrDrawImageBits(wid, gc, 0, 0, &image_jollen);
break;
case GR_EVENT_TYPE_CLOSE_REQ:
GrClose();
default: break;
}
}