使用SDL(Simple DirectMedia Layer)显示内存图像时窗口全白问题求助
问题诊断
- 代码中使用了未声明定义的
img指针:你已经手动定义了h=480、w=640的图像尺寸,但后续创建窗口、遍历赋值数组、创建表面时全部用了不存在的img->w、img->h,属于运行时严重逻辑错误。 - 8位灰度SDL表面未设置调色板:
SDL_CreateRGBSurfaceFrom创建8bit位深的索引色表面时,默认没有对应灰度映射的调色板,所有像素索引都会被映射为白色,这是显示全白的核心原因。 - 语法不规范:
main函数声明为void却返回0,不符合C标准;未引入必要头文件;调用完SDL_Init没有做错误检查。 - 错误释放窗口表面:
SDL_GetWindowSurface返回的表面由窗口内部管理,手动释放会导致程序崩溃。
修复方案
- 把所有
img->w、img->h替换为你自定义的w、h变量。 - 给8位灰度表面手动创建灰度调色板,让索引值0对应黑色(0,0,0)、索引值255对应白色(255,255,255),中间值线性映射。
- 修正
main函数返回值为int,移除winSurf的释放逻辑,补充基础错误检查。
修复后完整代码
#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <stdbool.h> #include <SDL2/SDL.h> int 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; if (SDL_Init(SDL_INIT_VIDEO) != 0) { printf("SDL初始化失败: %s\n", SDL_GetError()); return 1; } h = 480; w = 640; window = SDL_CreateWindow("CIMPL Image", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, (int)w, (int)h, SDL_WINDOW_ALLOW_HIGHDPI); if (!window) { printf("窗口创建失败: %s\n", SDL_GetError()); SDL_Quit(); return 1; } winSurf = SDL_GetWindowSurface(window); // 生成左侧为黑色、向右灰度值递增到白色的图像 data = malloc(sizeof(uint8_t) * (h * w)); if (!data) { printf("内存分配失败\n"); SDL_DestroyWindow(window); SDL_Quit(); return 1; } for (j = 0; j < h; ++j) { for (i = 0; i < w; ++i) { data[i + j * w] = (uint8_t)(i * 255 / w); // 适配不同宽度的灰度渐变 } } imgSurf = SDL_CreateRGBSurfaceFrom((void*)data, (int)w, (int)h, 8, w, 0, 0, 0, 0); if (!imgSurf) { printf("表面创建失败: %s\n", SDL_GetError()); free(data); SDL_DestroyWindow(window); SDL_Quit(); return 1; } // 补充灰度调色板 SDL_Color palette[256]; for (int k = 0; k < 256; k++) { palette[k].r = palette[k].g = palette[k].b = k; palette[k].a = 255; } SDL_SetPaletteColors(imgSurf->format->palette, palette, 0, 256); running = true; while (running) { if (SDL_WaitEvent(&sdlEvent)) { switch (sdlEvent.type) { case SDL_QUIT: running = false; break; } } SDL_BlitSurface(imgSurf, NULL, winSurf, NULL); SDL_UpdateWindowSurface(window); } SDL_FreeSurface(imgSurf); imgSurf = NULL; free(data); SDL_DestroyWindow(window); SDL_Quit(); return 0; }
内容的提问来源于stack exchange,提问作者user24205
相关产品推荐
相关产品推荐

