0

这很可能以前出现过,但以下代码取自我正在修改的 MSDN 示例。我想知道如何遍历包含位图数据的缓冲区的内容并打印出颜色。每个像素是 4 个字节的数据,所以我假设 RGB 值占这些字节中的 3 个,并且 A 可能是第 4 个。

所需的指针算术(理想情况下在循环内)的正确 C++ 语法是什么,它将在该迭代期间指向的值存储到我可以使用的局部变量中,例如。打印到控制台。

非常感谢

PS。这安全吗?或者有没有更安全的方法来读取 IMFMediaBuffer 的内容?我找不到替代方案。

这是代码:

hr = pSample->ConvertToContiguousBuffer(&pBuffer); // this is the BitmapData
    // Converts a sample with multiple buffers into a sample with a single IMFMediaBuffer which we Lock in memory next...

    // IMFMediaBuffer represents a block of memory that contains media data

    hr = pBuffer->Lock(&pBitmapData, NULL, &cbBitmapData);  // pBuffer is IMFMediaBuffer
    /* Lock method gives the caller access to the memory in the buffer, for reading or writing:
    pBitmapData - receives a pointer to start of buffer
    NULL - receives the maximum amount of data that can be written to the buffer. This parameter can be NULL.
    cbBitmapData - receives the length of the valid data in the buffer, in bytes. This parameter can be NULL.
    */
4

1 回答 1

0

我自己解决了这个问题,并认为最好在此处添加答案,以便它的格式正确,也许其他人会从中受益。基本上在这种情况下,我们使用 32 位的图像数据,而最棒的是我们正在从内存中读取原始数据,因此还没有要跳过的位图标头,因为这只是原始颜色信息。

注意:在这 4 个字节中,我们有(从位 0 到 31)BGRA,我们可以使用我的代码进行验证:

  int x = 0;

    while(x < cbBitmapData){

        Console::Write("B: {0}", (*(pBitmapData + x++)));
        Console::Write("\tG: {0}", (*(pBitmapData + x++)));
        Console::Write("\tR: {0}", (*(pBitmapData + x++)));
        Console::Write("\tA: {0}\n", (*(pBitmapData + x++)));
    }

从输出中,您将看到每个像素的 A 值为 0,因为这里没有透明度或深度的概念,这是我们所期望的。

还要验证我们在缓冲区中拥有的只是原始图像数据,没有其他数据,我使用了这个计算,你也可能会发现它有用:

Console::Write("no of pixels in buffer: {0} \nexpected no of pixels based on dimensions:{1}", (cbBitmapData/4), (m_format.imageWidthPels * m_format.imageHeightPels) );

我们将 的值cbBitmapData除以 4,因为它是字节数,如前所述,对于每个像素,我们有 4 个字节的宽度(DWORDS实际上是 32 位,因为一个字节的长度在硬件中并不总是严格一致的显然!?)。我们将其与图像宽度乘以其高度进行比较。它们是相等的,因此我们在缓冲区中只有像素颜色信息。

希望这可以帮助某人。

于 2011-07-05T07:39:27.170 回答