1. 程式人生 > >畫素操作

畫素操作


3.2 解決OpenGL常用的RGB畫素資料與BMP檔案的BGR畫素資料順序不一致問題
可以使用一些程式碼交換每個畫素的第一位元組和第三位元組,使得RGB的資料變成BGR的資料。當然也可以使用另外的方式解決問題:新版本的OpenGL除了可以使用GL_RGB讀取畫素的紅、綠、藍資料外,也可以使用GL_BGR按照相反的順序依次讀取畫素的藍、綠、紅資料,這樣就與BMP檔案格式相吻合了。即使你的gl/gl.h標頭檔案中沒有定義這個GL_BGR,也沒有關係,可以嘗試使用GL_BGR_EXT。雖然有的OpenGL實現(尤其是舊版本的實現)並不能使用GL_BGR_EXT,但我所知道的Windows環境下各種OpenGL實現都對GL_BGR提供了支援,畢竟Windows中各種表示顏色的資料幾乎都是使用BGR的順序,而非RGB的順序。這可能與IBM-PC的硬體設計有關。

3.3 消除BMP檔案中“對齊”帶來的影響

實際上OpenGL也支援使用了這種“對齊”方式的畫素資料。只要通過glPixelStore修改“畫素儲存時對齊的方式”就可以了。像這樣:
int alignment = 4;
glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
第一個引數表示“設定畫素的對齊值”,第二個引數表示實際設定為多少。這裡畫素可以單位元組對齊(實際上就是不使用對齊)、雙位元組對齊(如果長度為奇數,則再補一個位元組)、四位元組對齊(如果長度不是四的倍數,則補為四的倍數)、八位元組對齊。分別對應alignment的值為1, 2, 4, 8。實際上,預設的值是4,正好與BMP檔案的對齊方式相吻合。
glPixelStorei也可以用於設定其它各種引數。但我們這裡並不需要深入討論了。


現在,我們已經可以把螢幕上的畫素讀取到記憶體了,如果需要的話,我們還可以將記憶體中的資料儲存到檔案。正確的對照BMP檔案格式,我們的程式就可以把螢幕中的圖象儲存為BMP檔案,達到螢幕截圖的效果。
我們並沒有詳細介紹BMP檔案開頭的54個位元組的所有內容,不過這無傷大雅。從一個正確的BMP檔案中讀取前54個位元組,修改其中的寬度和高度資訊,就可以得到新的檔案頭了。假設我們先建立一個1*1大小的24位色BMP,檔名為dummy.bmp,又假設新的BMP檔名稱為grab.bmp。則可以編寫如下程式碼:

FILE* pOriginFile = fopen("dummy.bmp", "rb);
FILE* pGrabFile = fopen("grab.bmp", "wb");
char   BMP_Header[54];
GLint width, height;

/* 先在這裡設定好圖象的寬度和高度,即width和height的值,並計算畫素的總長度 */

// 讀取dummy.bmp中的頭54個位元組到陣列
fread(BMP_Header, sizeof(BMP_Header), 1, pOriginFile);
// 把陣列內容寫入到新的BMP檔案
fwrite(BMP_Header, sizeof(BMP_Header), 1, pGrabFile);

// 修改其中的大小資訊
fseek(pGrabFile, 0x0012, SEEK_SET);
fwrite(&width, sizeof(width), 1, pGrabFile);
fwrite(&height, sizeof(height), 1, pGrabFile);

// 移動到檔案末尾,開始寫入畫素資料
fseek(pGrabFile, 0, SEEK_END);

/* 在這裡寫入畫素資料到檔案 */

fclose(pOriginFile);
fclose(pGrabFile);
我們給出完整的程式碼,演示如何把整個視窗的圖象抓取出來並儲存為BMP檔案。