Problem with keying an image

I have been following the “Lazy Foo” game tutorials. I finished tutorial 5 which is located here: http://lazyfoo.net/SDL_tutorials/lesson05/index.php

However my result isn’t the same. I assume it’s because of compression in the image I used? I assume there is a 85% compression ratio or so on the jpegs I used. I right clicked and saved the ones at the start of the tutorial.

My end result looks like this (warning, large image):

http://ompldr.org/vNzFqYg/2011-01-18-210133_1920x1080_scrot.png

My complete source code is here (differs from the tutorial as I didn’t like the naming conventions and I am using C not C++).

Code:

#include <SDL/SDL.h>
#include <SDL/SDL_image.h>

const int SCREEN_WIDTH = 320;
const int SCREEN_HEIGTH = 240;
const int SCREEN_BPP = 32;

SDL_Surface *background = NULL;
SDL_Surface *foreground = NULL;
SDL_Surface *screen = NULL;

SDL_Event event;

//------------------------------------------------------------------------------------//

SDL_Surface *getOptimizedImage(char filename); / Returns the surface, NULL if error /
int displayImage(); /
Load the image and check for error */

void apply_to_surface(int x, int y, SDL_Surface *source, SDL_Surface destination);
/
Above function applies an optimized image to an available surface */

int init();
void cleanup();
//------------------------------------------------------------------------------------//

int main(int argc, char *argv[]){
if (init() == 1){
fprintf(stderr, “init() failed\n”);
return 1;
}

if (displayImage() == 1){
fprintf(stderr, “displayImage()\n”);
return 1;
}

apply_to_surface(0, 0, background, screen);
apply_to_surface( 140, 100, foreground, screen);

int quit = 0;
while(quit != 1){
while (SDL_PollEvent(&event)){
if (event.key.keysym.sym == SDLK_ESCAPE)
quit = 1;

  if (SDL_Flip(screen) == -1)
    return 1;
}

}
return 0;
}

//------------------------------------------------------------------------------------//

SDL_Surface *getOptimizedImage(char *filename){
SDL_Surface *tmp = IMG_Load(filename);
SDL_Surface *optimized = NULL;

if (tmp != NULL){
optimized = SDL_DisplayFormat(tmp);
SDL_FreeSurface(tmp);
}

if (optimized != NULL){
uint32_t colorkey = SDL_MapRGB(optimized->format, 0, 255, 255);
SDL_SetColorKey(optimized, SDL_SRCCOLORKEY, colorkey);
}
return optimized;
}

int displayImage(){
background = getOptimizedImage(“background.jpg”);
foreground = getOptimizedImage(“foo.jpg”);

if ((background == NULL)|| (foreground == NULL)){
fprintf(stderr, “Background or Foreground was null in displayImage()\n”);
return 1;
}
return 0;
}

void apply_to_surface(int x, int y, SDL_Surface *source, SDL_Surface *destination){
SDL_Rect screenoffset;
screenoffset.x = x;
screenoffset.y = y;

SDL_BlitSurface(source, NULL, destination, &screenoffset);
}

int init(){
if (SDL_Init(SDL_INIT_EVERYTHING) == -1){
fprintf(stderr, “SDL_INIT_EVERYTHING FAILED in init()\n”);
return 1;
}

screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGTH, SCREEN_BPP, SDL_SWSURFACE);

if (screen == NULL){
fprintf(stderr, “Screen was null in init()\n”);
return 1;
}

SDL_WM_SetCaption(“Fast Photo Viewer”, NULL); /* useless with DWM… */

return 0;
}

void cleanup(){
SDL_FreeSurface(background);
SDL_FreeSurface(foreground);
SDL_Quit();
}

Any ideas why this would occur? Should I be using uncompressed images, or bitmaps only for trying to key something ?

The issue is that JPEG uses a lossy compression algorithm. Quite often, pixel colors will shift slightly (not enough that you could notice on your screen, but that doesn’t matter to your computer or SDL; which look for exact values).

You may get similar results with GIF

Use PNG instead.------------------------
EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/

Thanks! I tested it out with a png and it worked perfect.