写点什么

SDL 图像显示

作者:柒号华仔
  • 2022 年 7 月 17 日
  • 本文字数:3043 字

    阅读完需:约 10 分钟

       计算机屏幕上的图像是由一个一个点组成的,不同颜色的点集合在一起,就构成了一幅图片。在屏幕上显示图像,就是对每一个像素点进行着色。首先我们对图片进行分析,取出每一个点的像素,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;

}


发布于: 刚刚阅读数: 6
用户头像

柒号华仔

关注

星光不问赶路人,时光不负有心人。 2022.07.01 加入

CSDN 5G领域新星创作者,阿里云星级博主,专注于5G领域,兼顾网络,编解码协议,linux,C/C++等方向,欢迎关注我。

评论

发布
暂无评论
SDL图像显示_7月月更_柒号华仔_InfoQ写作社区