在上一篇文章里,我们做了一个“加法”把两张图片合成,费了好大功夫才搞定,要是用PS可快了,我说哥们,这没可比性!现在要做减法,就好比你工作是挣钱,你总得花钱吧!上大学的时候,有这么一苦逼事,全班男生集体赌博,凭借着过硬技术和良好的心态,竟然横扫,373张1毛的钞票进了裤袋,那上面要是毛爷爷该多好!可惜的是它抵不过半个毛爷爷。回过头继续上小学,今天任务就是把图片支解。
这样做的好处是,如果你要用很多图片时,不停加截图片是不是很烦,不停进行(文件)IO操作也有风险,所以就集成一张图片,这就是昨天加法,下面是做减法的时候,就是取出图片里的具体图形。
#include "SDL/SDL.h" #include "SDL/SDL_image.h" #include <string> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; const int SCREEN_BPP = 32; SDL_Surface *dots = NULL; SDL_Surface *screen = NULL; //The event structure SDL_Event event; //The portions of the sprite map to be blitted 发现SDL_Rect了 SDL_Rect clip[ 4 ]; SDL_Surface *load_image( std::string filename ) { //The image that's loaded SDL_Surface* loadedImage = NULL; //The optimized surface that will be used SDL_Surface* optimizedImage = NULL; //Load the image loadedImage = IMG_Load( filename.c_str() ); //If the image loaded if( loadedImage != NULL ){ //Create an optimized surface optimizedImage = SDL_DisplayFormat( loadedImage ); //Free the old surface SDL_FreeSurface( loadedImage ); //If the surface was optimized if( optimizedImage != NULL ){ //Color key surface 对比上篇的代码发现有什么改进没?? SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ) ); } } //Return the optimized surface return optimizedImage; } void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL ) { //Holds offsets SDL_Rect offset; //Get offsets offset.x = x; offset.y = y; //Blit SDL_BlitSurface( source, clip, destination, &offset ); } bool init() { //Initialize all SDL subsystems if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 ) { return false; } //Set up the screen screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE ); //If there was an error in setting up the screen if( screen == NULL ){ return false; } //Set the window caption SDL_WM_SetCaption( "Split the dots", NULL ); //If everything initialized fine return true; } bool load_files() { //Load the sprite map dots = load_image( "dots.png" ); //If there was an problem loading the sprite map if( dots == NULL ){ return false; } //If eveything loaded fine return true; } void clean_up() { //释放图片内存 SDL_FreeSurface( dots ); //退出SDL SDL_Quit(); } int main( int argc, char* args[] ) { //关闭标志 bool quit = false; //初始化 if( init() == false ) { return 1; } //Load the files if( load_files() == false ) { return 1; } /*取图像 */ //Clip range for the top left 左上圆 clip[ 0 ].x = 0; clip[ 0 ].y = 0; clip[ 0 ].w = 100; clip[ 0 ].h = 100; //Clip range for the top right 右上圆 clip[ 1 ].x = 100; clip[ 1 ].y = 0; clip[ 1 ].w = 100; clip[ 1 ].h = 100; //Clip range for the bottom left 左下圆 clip[ 2 ].x = 0; clip[ 2 ].y = 100; clip[ 2 ].w = 100; clip[ 2 ].h = 100; //Clip range for the bottom right 右下圆 clip[ 3 ].x = 100; clip[ 3 ].y = 100; clip[ 3 ].w = 100; clip[ 3 ].h = 100; //先把整个窗口设为白色 SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0xFF, 0xFF, 0xFF ) ); //Apply the sprites to the screen 块移图片,把dots进行了分解块移 apply_surface( 0, 0, dots, screen, &clip[ 0 ] ); apply_surface( 540, 0, dots, screen, &clip[ 1 ] ); apply_surface( 200, 200, dots, screen, &clip[ 2 ] ); apply_surface( 540, 380, dots, screen, &clip[ 3 ] ); //Update the screen if( SDL_Flip( screen ) == -1 ) { return 1; } //While the user hasn't quit while( quit == false ) { //While there's events to handle while( SDL_PollEvent( &event ) ) { //If the user has Xed out the window if( event.type == SDL_QUIT ) { //Quit the program quit = true; } } } clean_up(); return 0; }
保存为sdl05.cpp 编译
g++ -o sdl05 sdl06.cpp -lSDL -lSDL_image ./sdl05
有图片有真相
果真如此吧,这个用法非常有用,因为在人物设计时往往是非常用效的。而如从不纯色的背景里取某个景特时,上述方法是不可取的。 因为他用到了透明处理,进行RGB图像映射。
而且更应该关注的事,当我们把其它窗口从上面拖过去的时候已经没有变成黑色的背景的现象,什么原因,留给后面再说吧。文章标题言过其实,就当是搏个眼球,当然人民肯定是能支解的,毛爷爷会变成工家兵,不过有机会一定要要试试支解下人民币。