Nano-X 程式設計, #3:顯示圖片(image.c)

jollen 發表於 January 13, 2007 8:41 PM

程式範例 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.89/
# cp src/bin/convbmp /usr/bin

先將取得的圖檔轉換成 BMP 的格式,再利用 convbmp 轉換成 C 程式。例如,我想轉換圖檔 jollen.bmp,那麼將圖檔轉換成 C 程式的指令就是:

$ convbmp jollen.bmp

jollen.bmp

圖(jollen.bmp)

轉換後便會得到 jollen.c。接著我們再修改 hello.c 將圖片顯示於視窗上。

如何將圖片顯示於視窗上

因為圖片資料屬於外部變數,因此先在程式裡宣告外部圖片變數:

extern GR_IMAGE_HDR image_jollen;

image_jollen 是一個陣列,存放圖檔的 pixel 資料,此陣列由 convbmp 轉換後產生,詳見 jollen.c 程式。接著,在處理 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 www.jollen.org
 *
 * - Nano-X API example.
 * - image.c
 */

#include <stdio.h>
#define MWINCLUDECOLORS
#include <microwin/nano-X.h>

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;
   }
}

注釋

  • 2007.01.13 編修(Revision)
Also See

Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue

您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw