我正在尝试将一组像素复制到更大的像素缓冲区中。显然,我计算出的坐标有误,可能是大步向前,但我找不到丢失的坐标。我得到了一个完全混乱的结果。
因此,从本质上讲,我想实现的目标是将 RGBA 像素阵列复制到更大的 RGB 阵列(alpha被丢弃)中,保持正确的步幅。请参见下图,以直观方式表示预期的结果。
void draw(const uint8_t* tileRGBA, uint8_t* canvasRGB, const int canvasStride,
const int tileWidth, const int tileHeight)
{
for (int y = 0; y < tileHeight; y++)
{
for (int x = 0; x < tileWidth; x++)
{
long tileIndex = (4 * x) + (y * tileWidth);
long canvasIndex = (3 * x) + (y * canvasStride);
canvasRGB[canvasIndex] = tileRGBA[tileIndex];
canvasRGB[canvasIndex + 1] = tileRGBA[tileIndex + 1];
canvasRGB[canvasIndex + 2] = tileRGBA[tileIndex + 2];
}
}
}
uint8_t* test(uint32_t* tileRGBA, const int tileWidth, const int tileHeight)
{
int canvasStride = tileWidth * 5; // 5 is just an arbitrary value for this example, in this case a canvas 5 times the width of the tile
uint8_t* canvasRGB = new uint8_t[canvasStride * tileHeight * 3];
draw((uint8_t*)tileRGBA, canvasRGB, canvasStride, tileWidth, tileHeight);
return canvasRGB;
}
已解决:感谢Johnny Mopp的评论。这是一个括号问题。
此:
long tileIndex = (4 * x) + (y * tileWidth)
long canvasIndex = (3 * x) + (y * canvasStride);
必须是这样:
long tileIndex = 4 * (x + y * tileWidth);
long canvasIndex = 3 * (x + y * canvasStride);
答案 0 :(得分:1)
问题出在您的索引计算中。
要在1D数组中获得2D索引(行,列),请执行以下操作:
index = ((number_of_columns * row) + col) * sizeof(data)
其中number_of_columns
是数据中预期的“列”数-在这种情况下为图像的宽度。 sizeof(data)
是数组中一项的大小(以字节为单位),在这种情况下,RGBA为4个字节,RGB为3个字节。因此,正如您所确定的,应该是:
long tileIndex = 4 * (x + y * tileWidth);
long canvasIndex = 3 * (x + y * canvasStride);
如果可以将数据表示为单个项目,则可以取消sizeof
乘法。例如,根据您的情况,创建2个结构:
struct RGB {
uint8_t r,g,b;
};
struct RGBA {
uint8_t r,g,b,a;
};
然后将参数作为这些结构的数组传递:
void draw(const RGBA* tileRGBA, RGB* canvasRGB, const int canvasStride, const int tileWidth, const int tileHeight)
然后将计算简化为:
long tileIndex = x + y * tileWidth;
long canvasIndex = x + y * canvasStride;