DevIL的學習筆記

        最近學習DevIL,一個比較不錯的載入多種圖片軟件。咱們在學習界面的時候,經常須要對這種那種圖片格式進行解碼,同時在這方面也有許多解決方案,例如獨立的cxImage、libpng、libjpeg、freeimage、FFmpeg、SOIL;或者嵌入到別的軟件的例如Qt、DirectX。網上說cxImage不錯,很多教材使用着一個庫,可是cxImage只能在VisualStudio編譯(應該能夠移植吧,不知道有沒有高手作到了,有時間確定要研究一下),並且在VisualStudio編譯配置還比較困難,再者cxImage已經中止更新了;SOIL......洗洗睡吧,連tga都載入不了;Qt也有解碼多種圖片的方案,可是離開了Qt就幹不了了;至於FFmpeg,學過用FFmpeg解碼音頻的讀者應該知道有多麻煩,直接使用確定很差用,並且大部分狀況應該不會搞得那麼細吧。總之,DevIL是一個比較不錯的API,尤爲對於學過OpenGL的讀者,對它的風格會感到很親切。ios

        我大概的學習了一下,發現問題在於全面的資料實在很難找,沒有像樣的官方資料,若是要深刻的瞭解着一個軟件,以適應各類實際運用的需求,例如控制圖片原點位置的功能,按理說DevIL應該有,可是官方文檔並無介紹,那麼應該找到它的參考文檔,通過了我不懈的努力,終於找到了一個詳細介紹其API的網站:http://www-f9.ijs.si/~matevz/docs/DevIL,雖然網頁依然很慢,但對於使用這一API的我已經很足夠了。學習

        下面介紹如下DevIL:網站

        DevIL原名爲OpenIL,不過在SGI要求下,變爲了DevIL(其實仍是跟Linux-Devil衝突......)。這是一個強大的圖形處理軟件,能夠載入導出多種格式(20多種,有一些仍是第一次見面)圖片、圖像處理(ILU模塊、好比濾波)、與其餘圖形庫配合使用(ILUT模塊,例如與OpenGL、DirectX配合)。並且器接口風格與OpenGL極其相似,使用起來就像OpenGL的一個擴展。在大多數Linux發行版中均可以看見。在apt中軟件名稱爲libdevil-dev。ui

        下面介紹一下基本使用方法。spa

#include <IL/il.h>
#include <iostream>
#include <cassert>

int main(){

    ILuint image;
    ILint width,height,type,format;
    ilInit();
    ilGenImages(1,&image);
    ilBindImage(image);
    assert(ilLoadImage("test.jpg"));
    ilGetIntegerv(IL_IMAGE_WIDTH,&width);
    ilGetIntegerv(IL_IMAGE_HEIGHT,&height);
    ilGetIntegerv(IL_IMAGE_TYPE,&type);
    ilGetIntegerv(IL_IMAGE_FORMAT,&format);
    cerr<<"Image Width:"<<width<<"\nImage Height:"<<height<<"\n";
    cerr<<"Image Type:";
    switch (format){
    case IL_RGB:cerr<<"RGB";break;
    case IL_RGBA:cerr<<"RGBA";break;
    case IL_BGR:cerr<<"BGR";break;
    case IL_BGRA:cerr<<"BGRA";break;
    case IL_COLOR_INDEX:cerr<<"Color Index";break;
    default:cerr<<"Other";break;
    }
    cerr<<"\nImage Type:";
    switch (type){
    case IL_UNSIGNED_BYTE:cerr<<"Unsigned Byte";break;
    case IL_BYTE:cerr<<"Byte";break;
    case IL_UNSIGNED_SHORT:cerr<<"UNisgned Short";break;
    case IL_SHORT:cerr<<"Short";break;
    case IL_UNSIGNED_INT:cerr<<"Unsigned Int";break;
    case IL_INT:cerr<<"Int";break;
    case IL_FLOAT:cerr<<"FLoat";break;
    case IL_DOUBLE:cerr<<"Double";break;
    default:cerr<<"Other";break;
    }
    cerr<<"\n";

    void * data=ilGetData();
    //載入data......

    ilBindImage(0);
    ilDeleteImges(1,&image);
    ilShutDown();

}

        學過OpenGL紋理的讀者應該知道,載入的紋理有可能原點跟OpenGL設定的(在左下角)不符,能夠這樣設置,就不用擔憂這個問題了:code

ilEnable(IL_ORIGIN_SET);
    ilOriginFunc(IL_ORIGIN_LOWER_LEFT);//or IL_ORIGIN_UPPER_LEFT

        能夠經過ilSetWrite、ilSetRead控制文件輸出輸入,在遊戲開發裏面頗有用,下面給一個嵌入PHYSFS的例子:orm

#include <physfs.h>
#include <IL/il.h>
#include <cassert>
#include <iostream>
#include <string>

ILint PHYSFS_getc(PHYSFS_File * file){
	if (!PHYSFS_eof(file)){
		char ch;
		PHYSFS_read(file,&ch,sizeof(char),1);
		return ch;
	}
	return 0;
}

ILint PHYSFS_putc(ILubyte ch,PHYSFS_File * file){
	return PHYSFS_write(file,&ch,sizeof(ILubyte),1);
}

ILint PHYSFS_cread(void * buffer,ILint objSize,ILint objCount,PHYSFS_File * file){
	return PHYSFS_read(file,buffer,objSize,objCount);
}

ILint PHYSFS_cwrite(void * buffer,ILint objSize,ILint objCount,PHYSFS_File * file){
	return PHYSFS_write(file,buffer,objSize,objCount);
}

ILint PHYSFS_cseek(PHYSFS_File * file,ILint offset,ILint flag){
	PHYSFS_sint64 length=PHYSFS_fileLength(file);
	PHYSFS_sint64 pos=0;
	switch (flag){
	case IL_SEEK_SET:pos=0;break;
	case IL_SEEK_CUR:return (ILint)PHYSFS_tell(file);
	case IL_SEEK_END:pos=length;break;
	}
	return PHYSFS_seek(file,pos);
}

int main(int argc,char * argv[]){

	using namespace std;
	
	ilInit();
	PHYSFS_init(argv[0]);

	PHYSFS_addToSearchPath(".",true);
	PHYSFS_setWriteDir(".");
	
	ilSetRead(
		(fOpenRProc)PHYSFS_openRead,
		(fCloseRProc)PHYSFS_close,
		(fEofProc)PHYSFS_eof,
		(fGetcProc)PHYSFS_getc,
		(fReadProc)PHYSFS_cread,
		(fSeekRProc)PHYSFS_cseek,
		(fTellRProc)PHYSFS_tell);
		
	ilSetWrite(
		(fOpenWProc)PHYSFS_openWrite,
		(fCloseWProc)PHYSFS_close,
		(fPutcProc)PHYSFS_putc,
		(fSeekWProc)PHYSFS_cseek,
		(fTellRProc)PHYSFS_tell,
		(fWriteProc)PHYSFS_cwrite);
	
	ILuint image;
	ilGenImages(1,&image);
	ilBindImage(image);
	assert(ilLoadImage("src.jpg"));
	ilSaveImage("dst.jpg");
	ilBindImage(0);
	ilDeleteImages(1,&image);
	
	PHYSFS_deinit();
	ilShutDown();
	
}

        這個樣接口

相關文章
相關標籤/搜索