2012-02-06 335 views
0

我目前正在关于在图像压缩中使用SDL的书。有一段代码可以在屏幕上显示图像,代码似乎读取图像,因为它会产生正确大小的窗口,但图像是黑色的。SDL生成黑色图像

我已经尝试了几个例子,所有的图像是黑色

我附上下面

#include <stdio.h> 
#include <stdlib.h> 
#include <SDL.h> 
#include <string.h> 

//A public class is the same as a 'struct' 
class CImage { 
public: 
    unsigned char red; 
    unsigned char green; 
    unsigned char blue; 
}; 


void ppm_read_comments (FILE *fp) 
{ 
    int c; 
    while ((c = getc (fp)) == '#') { 
    while ( getc(fp) != '\n') 
    ; 
    } 
    ungetc (c, fp); 
} 

class ppm_error 
{ 
    public: 
    ppm_error() { 
     printf("\nIncorrect PPM format!\n"); 
     exit (1); 
    } 
}; 


//change from (R, G, B) to (B, G, R) 
void ppm2sdl (CImage *ibuf, int width, int height) 
{ 
    unsigned char temp; 

    for (int i = 0; i < height; ++i) { 
    int row_offset = i * width; 
    for (int j = 0; j < width; ++j){ 
     int offset = row_offset + j; 
     temp = ibuf[offset].red; 
     ibuf[offset].red = ibuf[offset].blue; 
     ibuf[offset].blue = temp; 
    } 
    } 
} 

int main(int argc, char* args[]) 
{ 
    int ppmh[20], c;   //PPM header 
    int width, height;   //image width and height 
    SDL_Surface *screen; 
    char filename[] = "C:/data/beach.ppm"; 

    FILE *input = fopen (filename, "rb"); //PPM file for testing read 
    if (!input) { 
    printf("\nError opening input file %s!\n", filename); 
    return 1; 
    } 

    //read PPM input file 
    ppm_read_comments (input);  //read comments 
    char temp[100]; 
    fscanf (input, "%2s", temp); 
    temp[3] = 0; 
    if (strncmp (temp, "P6", 2)) 
    throw ppm_error(); 
    ppm_read_comments (input); 
    fscanf (input, "%d", &width); 
    ppm_read_comments (input); 
    fscanf (input, "%d", &height); 
    ppm_read_comments (input); 
    int colorlevels; 
    fscanf (input, "%d", &colorlevels); 
    printf("\n%s PPM file: ", temp); 
    printf(" \n\twidth=%d\theight=%d\tcolorlevles=%d\n", width,height,colorlevels+1); 
    ppm_read_comments (input); 
    while ((c = getc (input)) == '\n');  //get rid of extra line returns 
    ungetc (c ,input); 

    // May use CImage ibuf[width][height] if we do not use SDL_QUIT; 
    CImage *ibuf = (CImage *) malloc (width * height * 3); 
    fread (ibuf, 3, width * height, input); //read image data from file 
    fclose (input); 

    //initialize video system 
    if (SDL_Init(SDL_INIT_VIDEO) < 0) { 
    fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError()); 
    exit(1); 
    } 
    //ensure SDL_Quit is called when the program exits 
    atexit(SDL_Quit); //if not use this, we need to 
         // do house cleaning manually when program ends 

    //set video mode of width x height with 24-bit pixels 
    screen = SDL_SetVideoMode(width, height, 24, SDL_SWSURFACE); 
    if (screen == NULL) { 
     fprintf(stderr, "Unable to set %dx%d video: %s\n", width, height,   SDL_GetError()); 
     exit(1); 
    } 

    //convert PPM format (R, G, B) to SDL format (B, G, R) 
     ppm2sdl (ibuf, width, height); 

    screen->pixels = ibuf; //point framebuffer to data buffer 

    // ibuf needs to be dynamically allocated if SDL_QUIT is used 
    printf("update rect\n" ); 
    SDL_UpdateRect (screen, 0, 0, 0, 0); //blit data to screen 

    // SDL_Flip(screen); 
    // SDL_CreateRGBSurface(screen, 0, 0, 0, 0,0,0,0); 

    SDL_Delay (4000);  //delay 4 seconds before exit 
    printf("Displaying PPM image %s successful!\n", filename); 

    //do NOT free(ibuf) if use SDL_QUIT which does the house cleaning 
    return 0; 
} 

回答

3

我还没有与SDL工作了一段时间,但我觉得你的代码不应该手动更改屏幕表面的像素数据,即您不应该更改从SDL_SetVideoMode()获得的SDL_Surfacepixels

您可以使用SDL_CreateRGBSurfaceFrom()从您从ppm文件读取的像素数据创建表面,然后用SDL_BlitSurface()将其闪烁到屏幕上。