使用 SDL(简单直接媒体层)显示图像

Showing an image with SDL (Simple Directmedia Layer)

我有一张图像作为数组存储在内存中,其中的值介于 0 和 255 之间。我想使用 SDL 将此图像显示到屏幕上。我正在用 C 编写代码。

我根据在网上找到的教程编写了以下代码。我的印象是这应该显示图像。但是,无论我如何更改数据数组,我总是得到一个白色的 window.

谁能告诉我如何解决这个问题?非常感谢任何帮助。

void main( void ){
  SDL_Window* window;
  SDL_Surface* imgSurf;
  SDL_Surface* winSurf;
  SDL_Event sdlEvent;
  unsigned char* data;
  size_t i, j;
  bool running;
  size_t h, w;

  window = NULL;
  imgSurf = NULL;
  winSurf = NULL;
  SDL_Init( SDL_INIT_VIDEO | SDL_INIT_AUDIO );

  h = 480;
  w = 640;

  window = SDL_CreateWindow( "CIMPL Image", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
    (int) img->w, (int) img->h, SDL_WINDOW_ALLOW_HIGHDPI );

  winSurf = SDL_GetWindowSurface( window );

  // Make an image that's black on left and increasing to white on right
  data = malloc( sizeof( uint8_t ) * (h*w) );
  for( j=0; j < img->h; ++j ){
    for( i=0; i < img->w; ++i ){
      data[ i + j * img->w ] = (uint8_t) i;
    }
  }

  imgSurf = SDL_CreateRGBSurfaceFrom( (void*) data, (int) img->w, (int) img->h,
    8, w, 0, 0, 0, 0 );

  running = true;
  while( running ){

    if( SDL_WaitEvent( &sdlEvent ) ){
      // WaitEvent is appropriate if window responds to user events
      // If things happen without user events, use SDL_PollEvent

      switch( sdlEvent.type ){
        case SDL_QUIT:
          running = false;
          break;
      }
    }

    SDL_BlitSurface( imgSurf, NULL, winSurf, NULL );
    SDL_UpdateWindowSurface( window );
  }
  
  SDL_FreeSurface( imgSurf );  imgSurf = NULL;
  SDL_FreeSurface( winSurf );  winSurf = NULL;

  free( data );

  SDL_DestroyWindow( window );
  SDL_Quit();

  return 0;
}

来自SDL_CreateRGBSurface

Remarks

If depth is 4 or 8 bits, an empty palette is allocated for the surface.

来自SDL_Palette

Remarks

Each pixel in an 8-bit surface is an index into the colors field of the SDL_Palette structure stored in SDL_PixelFormat. An SDL_Palette should never need to be created manually. It is automatically created when SDL allocates an SDL_PixelFormat for a surface. The colors values of an SDL_Surface's palette can be set with SDL_SetPaletteColors().

这意味着,您必须在调色板中设置颜色,并且您分配的数据包含调色板中颜色的索引。

例如

/* pixels/indices */

data = malloc( sizeof( uint8_t ) * (h*w) );
for (j=0; j < img->h; ++j) {
    for (i=0; i < img->w; ++i) {
        data[ i + j * img->w ] = (uint8_t) (((float) i / (float) img->w) * 255);
    }
}

/* surface */

imgSurf = SDL_CreateRGBSurfaceFrom( 
    (void*) data, 
    (int) img->w, (int) img->h, 
    8, w, 
    0, 0, 0, 0
);

/* palette */

SDL_Color colors[256];

for (int i=0; i < 256; ++i)
   colors[i].r = colors[i].g = colors[i].b = (Uint8)i;

SDL_SetPaletteColors(imgSurf->format->palette, colors, 0, 256);