(照翻教程)现在你即将要学习如何使用color key,用English来说就是这个教程将要教你如何在使用一个表面的时候将其背景色去掉。SDL_Surface结构有一个叫做color key的结构,也就是代表了你在bliting表面的时候不想予以显示的颜色,当你想使用透明表面的时候这个是灰常有用滴!
如图,小人的背景是青色的(R:0,G:FF,B:FF),那么我们现在要将小人背景透明化,则现在的color key就是青色的。
![SDL学习(四) <wbr>Color <wbr>Keying(抠色) SDL学习(四) <wbr>Color <wbr>Keying(抠色)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![SDL学习(四) <wbr>Color <wbr>Keying(抠色) SDL学习(四) <wbr>Color <wbr>Keying(抠色)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
color key 通常设置在图片装载的时候。
#include"SDL.h"
#include<string>
//窗口层显示宽高和像素位设置
const int SCREEN_WIDTH=640;
const int SCREEN_HEIGHT=480;
const int SCREEN_BPP=32;
//表面指针
SDL_Surface *foo=NULL;
SDL_Surface *screen=NULL;
SDL_Surface *background=NULL;
//装载图像的函数
SDL_Surface *load_image(std::string filename)
{
//旧图像的暂存指针
SDL_Surface *loadImage=NULL;
//最优化以后的图像指针
SDL_Surface *optimizedImage=NULL;
loadImage=IMG_Load(filename.c_str());
if(loadImage!=NULL)
{//判断是否已经装载成功,如果成功就将旧版本图像做优化使其像素位适应当前的创库显示
//创建最优化图像
optimizedImage=SDL_DisplayFormat(loadImage);
//注意要记得释放旧版本的图像
SDL_FreeSurface(loadImage);
if(optimizedImage!=NULL)
{//指定colorkey
Uint32 colorkey=SDL_MapRGB(optimizedImage->format,0,0xFF,0xFF);
//SDL_MapRGB可以将我们给定的rgb映射成传入surface的像素格式
//设置青色透明
SDL_SetColorKey(optimizedImage,SDL_SRCCOLORKEY,colorkey);//SDL_SRCCOLORKEY标志保证我们在blit表面的时候是设置透明的
}
return optimizedImage;
}
}
//实现将源表面与目标表面做链接的函数
void apply_surface(int x,int y,SDL_Surface *source,SDL_Surface *destination)
{//x和y决定了源表面在目标表面的相对位置
//建立一个矩形来存储偏移量,SDL_Rect是一个能代表一个矩形区域的数据类型,它有x,y的offset参数,还有其自身width和height
SDL_Rect offset;
//给矩形的偏移赋值,如此做的原因是SDL_BlitSurface函数仅仅接受通过SDL_Rect传过来的偏移量
offset.x=x;
offset.y=y;
//链接源和目标表面
SDL_BlitSurface(source,NULL,destination,&offset);
}
int main(int argc,char *argv[])
{
if(SDL_Init(SDL_INIT_EVERYTHING==-1))
{//当初始化失败的时候,SDL会返回-1,此时我们就要通过返回1的错误句柄来终止程序
return 1;
}
//创建屏幕
screen=SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_SWSURFACE);
if(screen==NULL)
{
return 1;
}
//设置窗口标题
SDL_WM_SetCaption("ColorKey",NULL);
foo=load_image("D:/Users/lucy/Documents/Visual Studio 2008/Projects/SDLtest/foo.png");
if(foo==NULL)
{
return 1;
}
background=load_image("D:/Users/lucy/Documents/Visual Studio 2008/Projects/SDLtest/background.png");
if(background==NULL)
{
return 1;
}
//在屏幕上应用背景,因为图片不够大所以只能够填满屏幕的一部分所以要四次调用链接函数将整个屏幕填满
apply_surface(0,0,background,screen);
apply_surface(240,190,foo,screen);
if(SDL_Flip(screen)==-1)
{
return 1;
}
SDL_Delay(1000);
SDL_FreeSurface(foo);
SDL_FreeSurface(background);
SDL_Quit();
return 0;
}
后记:
使用上面的代码的时候不知道为什么总是不能正常的装载图片,于是看了一下各个函数的介绍和surface的formate结构如下
1.int SDL_SetColorKey(SDL_Surface *surface,Uint32 flag,Unit32 key) 【抠色函数】
里面key就是要抠掉的颜色
2.Uint32 SDL_MapRGB(SDL_PixelFormat *fmt,Unit8 r,Uint 8 ,Uint8 b)【RGB映射函数】
fmt是一个颜色格式,通常会使用作为被抠色的矩形图片的颜色格式,下面是一个SLD_Surface结构
typedef struct SDL_Surface {
Uint32 flags;
SDL_PixelFormat *format;
int w,h;
Uint16 pitch;
void *pixels;
SDL_Rect clip_rect;
int refcount;
}
3.void DisplaySurface::colorKey(Uint8 r,Uint g,Uint32 b,Uint32 flag)
设置抠色模式函数,flag是位标,一般有三种模式,SDl_SRCCOLORKEY,表示正常抠色,
SDL_SRCCOLORKEY|SDL_RLEACCEL 表示将抠色以后的图片重新编码,(通常意味着重复使用的时候会快一些)
作为背景的颜色,一般选择’无红满绿满蓝'或者‘满红无绿满蓝’