SDL3提取Surface像素RGB值失败,亮度对比度滤镜异常
解决SDL3中SDL_GetRGB返回(0,0,0)及图像变黑的问题
你的代码里有两个关键错误导致了读取像素RGB全为0、调节滑块后图像变黑的问题:
- 参数类型误用:
SDL_GetRGB和SDL_MapRGB需要传入SDL_PixelFormat*类型的像素格式,但你用了SDL_PixelFormatDetails*(SDL3新增的结构体,用于获取格式详细信息,不能直接替代原有的像素格式指针)。 - 参数顺序错误:
SDL_GetRGB的函数签名是void SDL_GetRGB(Uint32 pixel, const SDL_PixelFormat* format, Uint8 *r, Uint8 *g, Uint8 *b),你错误地把NULL(原本想忽略alpha通道)放在了红通道指针的位置,导致参数完全错位,无法正确解析像素的RGB值。
修正后的代码
void brightness_contrast_effect(SDL_Surface* surface, int brightness, int contrast) { if(SDL_MUSTLOCK(surface)) { SDL_LockSurface(surface); } Uint8 r,g,b; Uint32* pixels = (Uint32*) surface->pixels; // 直接使用surface的像素格式,而非SDL_PixelFormatDetails const SDL_PixelFormat* pixelFormat = surface->format; float contrast_factor = (259.0f * (contrast + 255)) / (255.0f * (255 - contrast)); std::cout << "contrast_value: " << std::fixed << std::setprecision(4) << contrast_factor << std::endl; for(int y = 0; y < surface->h; y++) { for (int x = 0; x < surface->w ; x ++) { Uint32* pixel = pixels + (y * surface->w + x); // 修正SDL_GetRGB的参数顺序,不需要传alpha参数时直接传r、g、b指针 SDL_GetRGB(*pixel, pixelFormat, &r, &g, &b); // 亮度调整 r = SDL_clamp(r + brightness, 0 , 255); g = SDL_clamp(g + brightness, 0 , 255); b = SDL_clamp(b + brightness, 0 , 255); // 对比度调整,显式转换为Uint8避免精度问题 r = SDL_clamp(static_cast<Uint8>((contrast_factor * (r - 128)) + 128.0f), 0 , 255); g = SDL_clamp(static_cast<Uint8>((contrast_factor * (g - 128)) + 128.0f), 0 , 255); b = SDL_clamp(static_cast<Uint8>((contrast_factor * (b - 128)) + 128.0f), 0 , 255); // 修正SDL_MapRGB的参数,使用SDL_PixelFormat*而非SDL_PixelFormatDetails* *pixel = SDL_MapRGB(pixelFormat, r, g, b); } } if(SDL_MUSTLOCK(surface)) { SDL_UnlockSurface(surface); } }
额外说明
- 对比度计算后的结果是浮点数,显式转换为
Uint8可以避免隐式转换可能导致的精度丢失或类型错误。 SDL_PixelFormatDetails的正确用法是通过SDL_GetPixelFormatDetails获取格式的详细信息(比如位深、通道顺序等),但不能直接用于SDL_GetRGB这类像素解析/映射函数。
内容的提问来源于stack exchange,提问作者Oscar Ramos
相关产品推荐
相关产品推荐

