2019独角兽企业重金招聘Python工程师标准>>>
最近学习DevIL,一个比较不错的载入多种图片软件。我们在学习界面的时候,常常需要对这种那种图片格式进行解码,同时在这方面也有许多解决方案,例如独立的cxImage、libpng、libjpeg、freeimage、FFmpeg、SOIL;或者嵌入到别的软件的例如Qt、DirectX。网上说cxImage不错,不少教材使用着一个库,但是cxImage只能在VisualStudio编译(应该可以移植吧,不知道有没有高手做到了,有时间肯定要研究一下),而且在VisualStudio编译配置还比较困难,再者cxImage已经停止更新了;SOIL......洗洗睡吧,连tga都载入不了;Qt也有解码多种图片的方案,但是离开了Qt就干不了了;至于FFmpeg,学过用FFmpeg解码音频的读者应该知道有多麻烦,直接使用肯定不好用,而且大部分情况应该不会搞得那么细吧。总之,DevIL是一个比较不错的API,尤其对于学过OpenGL的读者,对它的风格会感到很亲切。
我大概的学习了一下,发现问题在于全面的资料实在很难找,没有像样的官方资料,如果要深入的了解着一个软件,以适应各种实际运用的需求,例如控制图片原点位置的功能,按理说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。
下面介绍一下基本使用方法。
#include
#include
#include
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:"<
学过OpenGL纹理的读者应该知道,载入的纹理有可能原点跟OpenGL设定的(在左下角)不符,可以这样设置,就不用担心这个问题了:
ilEnable(IL_ORIGIN_SET);
ilOriginFunc(IL_ORIGIN_LOWER_LEFT);//or IL_ORIGIN_UPPER_LEFT
可以通过ilSetWrite、ilSetRead控制文件输出输入,在游戏开发里面很有用,下面给一个嵌入PHYSFS的例子:
#include
#include
#include
#include
#include
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();
}
这个样