如何将像素缓冲区复制到更大的缓冲区

时间:2018-08-14 13:07:14

标签: c++ arrays copy pixels

我正在尝试将一组像素复制到更大的像素缓冲区中。显然,我计算出的坐标有误,可能是大步向前,但我找不到丢失的坐标。我得到了一个完全混乱的结果。

因此,从本质上讲,我想实现的目标是将 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;
}

enter image description here

enter image description here

已解决:感谢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);

1 个答案:

答案 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;