如何从 SDL_Surface 获取特定像素的颜色?
Posted
技术标签:
【中文标题】如何从 SDL_Surface 获取特定像素的颜色?【英文标题】:How to get the color of a specific pixel from SDL_Surface? 【发布时间】:2018-10-28 17:00:06 【问题描述】:我正在尝试从 SDL_Surface 获取像素的 RGB/RGBA 颜色。我在互联网上找到了这段代码,但它返回了奇怪的数字(67372036 代表 0 红色、0 绿色、255 蓝色的像素)
Uint32 get_pixel32(SDL_Surface *surface, int x, int y)
Uint32 *pixels = (Uint32 *)surface->pixels;
return pixels[(y * surface->w) + x];
这是我一直在使用的代码:
Uint32 data = get_pixel32(gSurface, 0, 0);
printf("%i", data);
我不确定我的像素是否为 32 位格式,但其他图片效果不佳。
【问题讨论】:
请注意,y * surface->w
是错误许多图像的“间距”大于其宽度。
@BradAllred 像素[(y * surface->w) + x] 如果表面使用 32 位格式,则没有错。
@Nelfeal 保证书写在哪里?即使这是真的,您仍然可以使用 可移植到其他格式的surface->pitch
。无论如何,OP 明确表示他不知道格式,因此不能做出这样的假设。
@BradAllred 虽然我同意没有书面保证,但我很确定这是真的。查看 SDL_pixels.c 中的 SDL_CalculatePitch
:pitch = surface->w * surface->format->BytesPerPixel
,如果它是 32 位格式。我的回答解决了它取决于格式的事实。我的意思是函数本身没有错。
@Nelfeal SDL_CalculatePitch
在 SDL 分配自己的像素缓冲区时使用(例如通过 SDL_CreateRGBSurface
)。 SDL_CreateRGBSurfaceFrom
将接受您通过的 任何 音高。一个大于宽度*bpp 的真实示例是拥有一个巨大的精灵表图像和许多共享来自主图像的像素的子图像。您将有许多间距为master->w * bpp - sub->w * bpp
的微小表面。也许对你或 OP 来说并不重要,但为什么要误导别人呢?
【参考方案1】:
找到了这段代码,它工作正常。
Uint32 getpixel(SDL_Surface *surface, int x, int y)
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to retrieve */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch (bpp)
case 1:
return *p;
break;
case 2:
return *(Uint16 *)p;
break;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
return p[0] << 16 | p[1] << 8 | p[2];
else
return p[0] | p[1] << 8 | p[2] << 16;
break;
case 4:
return *(Uint32 *)p;
break;
default:
return 0; /* shouldn't happen, but avoids warnings */
SDL_Color rgb;
Uint32 data = getpixel(gSurface, 200, 200);
SDL_GetRGB(data, gSurface->format, &rgb.r, &rgb.g, &rgb.b);
【讨论】:
为什么对于每像素 3 个字节的格式只有一个字节顺序修复?不是每个像素格式(当然,每个像素格式 1 个字节除外)都需要在大端系统上重新排序相同的字节吗? @monkey0506:因为每像素 3 字节的格式会执行 3 次单独的内存访问,然后手动排序并组合成单个机器排序值。将其与 2 字节和 4 字节的情况进行对比,后者使用本地机器排序使用单个内存访问。【参考方案2】:这取决于表面的颜色格式,或SDL_PixelFormat
。您可以关注该页面上显示的内容,或者只使用SDL_GetRGB
。
【讨论】:
试过了,但它不起作用,因为 get_pixel32 函数只支持 32 位像素,我发现我的表面每个像素有 8 位。找到了另一个函数来获取多个像素大小的像素数据。以上是关于如何从 SDL_Surface 获取特定像素的颜色?的主要内容,如果未能解决你的问题,请参考以下文章