如何在 C 中用新的/更新的像素阵列更新/替换 SDL Surface 像素阵列?
Posted
技术标签:
【中文标题】如何在 C 中用新的/更新的像素阵列更新/替换 SDL Surface 像素阵列?【英文标题】:How do I update/replace an SDL Surface pixel array with a new/updated pixel array in C? 【发布时间】:2020-05-25 20:30:13 【问题描述】:我正在尝试使用 SDL 使单色图像出现在屏幕上。所以我拥有的数组将具有 0x00 或 0xFF 的值。
首先,我制作了一个 200x200 的小窗口,创建了一个新表面,使用 FillRect 将其设置为黑色。当我打印出音高和像素格式时,我得到 800 的音高和 rgb888 的格式。如果我理解正确,这意味着表面->像素的尺寸是 800x200,因为每个像素都附加了 2 个字节的信息?
我不明白的是,如果我想将该表面像素阵列更改为完全不同的东西,阵列的格式是什么?如果我有一个包含一个像素 [0xFF] 的简单数组,那么为表面的 RGB 值格式化的数组是否会是 [0xFF, 0xFF, 0xFF]?对于我想在屏幕上更改的每个像素,我需要更新数组中的三个值吗?
在我弄清楚如何格式化数组后,它是否像surface->pixels = newArray一样简单?然后更新窗口表面之后?
【问题讨论】:
【参考方案1】:看SDL_pixels.h
:
#define SDL_DEFINE_PIXELFORMAT(type, order, layout, bits, bytes) \
((1 << 28) | ((type) << 24) | ((order) << 20) | ((layout) << 16) | \
((bits) << 8) | ((bytes) << 0))
对于RGB888
,我们有:
SDL_PIXELFORMAT_RGB888 =
SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XRGB,
SDL_PACKEDLAYOUT_8888, 24, 4),
对于SDL_PACKEDORDER_*
,我们有:
/** Packed component order, high bit -> low bit. */
所以,每个像素都是一个 [packed] 32 unsigned int,取入 32 位整数时的顺序是:
X | R | G | B
对于小端机器,在内存中的顺序是颠倒的:
B | G | R | X
但是,请参阅下面的警告...
如果我理解正确,这意味着表面->像素的尺寸是 800x200,因为每个像素都附加了额外的 2 个字节的信息?
不,每个像素是 4 字节,只有 3 个 [有用] 值(如上以 32 位整数查看)。
等式是:
pitch = number_of_bytes_per_pixel_in_memory * width
对你来说,是:800 = 4 * 200
该格式可以更改RGB
字节的顺序,以及第四个字节是否具有任何价值(例如,RGBA
格式的透明度/alpha 混合)。
对于RGB888
,以下是我为说明而编写的一些转换函数:
typedef unsigned int u32;
typedef unsigned char byte;
enum
RSHF = 16,
GSHF = 8,
BSHF = 0,
;
// rgb2pixel -- convert RGB values to pixel value
u32
rgb2pixel(byte r,byte g,byte b)
u32 pix;
pix = 0;
pix |= ((u32) r) << RSHF;
pix |= ((u32) g) << GSHF;
pix |= ((u32) b) << BSHF;
return pix;
// pix2red -- extract red from RGB pixel
byte
pix2red(u32 pix)
byte color;
color = pix >> RSHF;
return color;
// pix2green -- extract green from RGB pixel
byte
pix2green(u32 pix)
byte color;
color = pix >> GSHF;
return color;
// pix2blue -- extract blue from RGB pixel
byte
pix2blue(u32 pix)
byte color;
color = pix >> BSHF;
return color;
警告:我不完全确定“打包的组件订单”是什么意思。
我对上述顺序的解释假设它是像素被提取为 32 位整数值之后的顺序。
但是,它可能意味着它是内存中的顺序,在这种情况下,我上面创建的图表将被颠倒。
如果您从以下位置存储所有值:
rgb2pixel(0xFF,0x00,0x00)
你应该得到一个红色的背景。如果你换成蓝色,那么RSHF
和BSHF
应该互换。
【讨论】:
感谢详细回答,但我必须注意,音高公式仅在特定情况下是正确的。如果格式是例如RGB24
(未打包到 32 位,每个像素为 3 个字节)然后行将被填充为 4 字节对齐,并且间距将反映最后的间隙(最后的 0-3 个额外字节,取决于宽度)。跨度>
以上是关于如何在 C 中用新的/更新的像素阵列更新/替换 SDL Surface 像素阵列?的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在 Apollo Client 中用新 id 更新或替换缓存条目的 id?
如何在 ng-bootstrap 轮播中用 div 替换图像?