SDL 图像显示
计算机屏幕上的图像是由一个一个点组成的,不同颜色的点集合在一起,就构成了一幅图片。在屏幕上显示图像,就是对每一个像素点进行着色。首先我们对图片进行分析,取出每一个点的像素,CPU 会将其保存在显存中,然后计算机会根据保存的像素,在屏幕上从上到下逐行逐点显示出来。 计算机用分辨率来表示有多少个点,800X600,1024X648 等,第一个数字表示屏幕宽,第二个表示屏幕的高。用二维坐标系 X,Y 来表示计算机屏幕。我们要在屏幕哪个位置画图象,就可以设置 X,Y 坐标。 我们需要三个参数,屏幕宽、高以及像素色彩位数。
SCREEN_WIDTH 屏幕宽度
SCREEN_HEIGHT 屏幕高度
SCREEN_BPP 屏幕所使用的像素色彩位数
SDL_image 库的使用
SDL 默认只支持 bmp 格式的图片显示,而大多数情况下,我们需要显示 jpeg,png 格式图片,这时候我们需要使用 SDL 扩展库。在开发前应先确认 SDL_image 库是否已编译安装成功。
首先需要先下载 SDL_image,可以从 SDL 的官网获取最新版本。你也可以从其中的“Libraries”章节下载这个库,就在 SDL 的主页上。如果你不想为此麻烦,在本文件夹内已有 SDL_image-1.2.10.tar.tar,只需按照《SDL 编译移植文档》安装即可。
在程序中使用 SDL_ttf 库,必须使用如下头文件,注意 SDL 是大写
#include<SDL_image.h>
Linux 应用程序链接时要也要链接这个库的-lSDL_image。
SDL_image 编程
BMP 格式的图片为例:
初始化
先对屏幕进行初始化,使用函数 SDL_SetVideoMode(w,h, desired_bpp, video_flags)来完成,设定屏幕参数。
下载图片到内存
设置好后,导入位图,将其下载于内存中,bmpfile 为选定的图片名:
img = SDL_LoadBMP(filename);图象如果导入正确,就将保存在 img 参数中。
建立最佳图像
如果有较多图片,有可能是 32 位的,也有可能是 24 位的。为了提高显示速度,我们应该在显示之前将所有图象的格式转换成一样的。使用 SDL_DisplayFormat 函数将图象的格式转换为同屏幕相同的格式。
newimg = SDL_DisplayFormat( img );
假设我们导入到 img 中的图象是 24 位的,但屏幕的格式是 32 位的。经过 SDL_DisplayFormat 函数转换后,图象格式就变成了 32 位,然后保存在 newimg 中。对于原来 24 位的图象 img,我们就不需要,就要调用 SDL_FreeSurface 函数去释放它。
显示图像
导入成功后,我们需将图像显示出来。
SDL_BlitSurface(newimg, &clip,screen,&dst) newimg 为要显示的图片;clip 为图片参数;screen 为屏幕,也可以是一张图片;dst 为显示位置。将 newimg 图象按照 dst 规定的坐标贴在 screen 屏幕上。 刷新屏幕变化部分: SDL_UpdateRects(screen,1,&dst) 这样,我们就将一幅 BMP 格式的图片显示在屏幕上。
有时候我们需要显示一张图片的一部分,只需对上面的参数 SDL_Rect*clip 进行定义就可实现。
释放内存
使用 SDL_FreeSurface(newimg);
Jpeg、png 图片显示
与 bmp 格式图片显示有两点不同:
首先是把 SDL_LoadBMP 改成 IMG_Load。
其次,把 SDL_DisplayFormat 改成 SDL_DisplayFormatAlpha。BMP 文件不支持 alpha 通道的吧,但 PNG 却支持。如果想留住 alpha 通道,那就需要用 SDL_DisplayFormatAlpha 来代替 SDL_DisplayFormat。
例程如下(编译时注意链接-lSDL_image):
#include
SDL_Surface*screen,*map;
staticvoid quit(int rc)
{
SDL_Quit();
exit(rc);
}
voidShowMap(char *filename,int x,int y)
{
SDL_Rectoffset;
map= IMG_Load(filename);
if(map== NULL){
fprintf(stderr,"Couldn'tload %s:%s\n",filename,SDL_GetError());
quit(1);
}
offset.x= x;
offset.y= y;
SDL_BlitSurface(map,NULL,screen,&offset);
SDL_UpdateRects(screen,1,&offset);
SDL_FreeSurface(map);
}
intmain(int argc,char *argv[])
{
char*file;
intw,h;
Uint8bpp;
Uint32flags;
w= 320;
h= 240;
bpp= 0;
flags= SDL_SWSURFACE;
if(SDL_Init(SDL_INIT_VIDEO)< 0){
fprintf(stderr,"Couldn'tinitialize SDL:%s\n",SDL_GetError());
return(1);
}
if((screen=SDL_SetVideoMode(w,h,bpp,flags))== NULL){
fprintf(stderr,"Couldn'tset %dx%dx%d video mode: %s\n",w,h,bpp,SDL_GetError());
quit(1);
}
SDL_WM_SetCaption("SDLjice","jicetest");
ShowMap("maps/Pepe.jpg",0,0);
ShowMap("maps/100.bmp",100,50);
SDL_Delay(1000);
SDL_Quit();
return0;
}
Agar 压缩或放大图片
在许多应用中,我们需要将图片完整的显示在屏幕中,或者根据需要大小来指定显示图片的大小。而图片的尺寸经常与我们所需要的尺寸不一致,即使将图片在规定的尺寸内显示出来,也会因为图片太大而显示速度很慢,或者因为图片太小而严重失真。因此,我们需要将大图片压缩至指定大小,将小图片放大至指定大小。
使用函数 int AG_ScaleSurface(AG_Surface *ss, Uint16 w, Uint16 h, AG_Surface **ds); ss 为需要处理的图片,w、h 表示按照宽为 w,高为 h 来处理图片,ds 为处理后的图片。
/*压缩或放大任意图片到指定大小*/
SDL_Surface *ProcessScaled(AG_Pixmap *px,AG_Surface *su,int surface_name) { unsigned int w,h;
char path[1024];
printf("get Scaled now ____-----____\n");
w = 320;
h = 240;
SDL_Surface *scaled = NULL;
if(AG_ScaleSurface(su,w,h,&scaled) == -1) {
AG_FatalError(NULL);
}
printf("get Scaled End\n") ;
return scaled;
}
版权声明: 本文为 InfoQ 作者【柒号华仔】的原创文章。
原文链接:【http://xie.infoq.cn/article/20e8e3105499e674f2102ff13】。文章转载请联系作者。
评论