Chinaunix首页 | 论坛 | 博客

分类: C/C++

2011-01-25 20:03:09

         计算机屏幕上的图像是由一个一个点组成的,不同颜色的点集合在一起,就构成了一幅图片。在屏幕上显示图像,就是对每一个像素点进行着色。首先我们对图片进行分析,取出每一个点的像素,CPU会将其保存在显存中,然后计算机会根据保存的像素,在屏幕上从上到下逐行逐点显示出来。
        
计算机用分辨率来表示有多少个点,800X6001024X648等,第一个数字表示屏幕宽,第二个表示屏幕的高。用二维坐标系XY来表示计算机屏幕。我们要在屏幕哪个位置画图象,就可以设置XY坐标。
        
我们需要三个参数,屏幕宽、高以及像素色彩位数。
         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

         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);

         Jpegpng图片显示

         bmp格式图片显示有两点不同:

         首先是把 SDL_LoadBMP改成IMG_Load

         其次,把SDL_DisplayFormat改成SDL_DisplayFormatAlphaBMP文件不支持alpha通道的吧,但PNG却支持。如果想留住alpha通道,那就需要用SDL_DisplayFormatAlpha来 代替SDL_DisplayFormat

         例程如下(编译时注意链接-lSDL_image):

        #include

        SDL_Surface *screen,*map;

        static void quit(int rc)

        {

           SDL_Quit();

           exit(rc);

         }

         void ShowMap(char *filename,int x,int y)

        {

           SDL_Rect offset;

           map = IMG_Load(filename);

           if(map == NULL){

                  fprintf(stderr,"Couldn't load %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);

              }

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

             {

            char *file;

            int w,h;

            Uint8 bpp;

            Uint32 flags;

            w = 320;

            h = 240;

            bpp = 0;

            flags = SDL_SWSURFACE;

            if(SDL_Init(SDL_INIT_VIDEO) < 0){

                     fprintf(stderr,"Couldn't initialize SDL:%s\n",SDL_GetError());

                     return (1);

            }

            if((screen=SDL_SetVideoMode(w,h,bpp,flags)) == NULL){

                     fprintf(stderr,"Couldn't set %dx%dx%d video mode: %s\n",w,h,bpp,SDL_GetError());

                     quit(1);

            }

            SDL_WM_SetCaption("SDL jice","jicetest");

            ShowMap("maps/Pepe.jpg",0,0);

            ShowMap("maps/100.bmp",100,50);

            SDL_Delay(1000);

            SDL_Quit();

            return 0;

                }

Agar压缩或放大图片

在许多应用中,我们需要将图片完整的显示在屏幕中,或者根据需要大小来指定显示图片的大小。而图片的尺寸经常与我们所需要的尺寸不一致,即使将图片在规定的尺寸内显示出来,也会因为图片太大而显示速度很慢,或者因为图片太小而严重失真。因此,我们需要将大图片压缩至指定大小,将小图片放大至指定大小。

       使用函数
                  int
AG_ScaleSurface(AG_Surface *ss, Uint16 w, Uint16 h, AG_Surface **ds)
       ss为需要处理的图片,wh表示按照宽为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;

     }

                       

          author:  jice           Email:chenhua2820@163.com          time:  2011-01-25

阅读(4308) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~