从媒体缓冲区读取 - 指针算术 C++句法

发布于 2024-11-18 07:17:34 字数 1070 浏览 4 评论 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.
    */

This may well have come up before but the following code is taken from an MSDN example I am modifying. I want to know how I can iterate through the contents of the buffer which contains data about a bitmap and print out the colors. Each pixel is 4 bytes of data so I am assuming the R G B values account for 3 of these bytes, and possibly A is the 4th.

What is the correct C++ syntax for the pointer arithmetic required (ideally inside a loop) that will store the value pointed to during that iteration in to a local variable that I can use, eg. print to the console.

Many thanks

PS. Is this safe? Or is there a safer way to read the contents of an IMFMediaBuffer? I could not find an alternative.

Here is the code:

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.
    */

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

苄①跕圉湢 2024-11-25 07:17:34

我自己解决了这个问题,并认为最好在此处添加答案,以便其格式正确,也许其他人会从中受益。基本上在这种情况下,我们使用 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 个字节(实际上是 32 位 DWORDS,因为字节的长度显然在不同硬件上并不总是严格一致!?) 。我们将其与图像宽度乘以高度进行比较。它们是相等的,因此我们在缓冲区中只有像素颜色信息。

希望这对某人有帮助。

I solved the problem myself and thought it best to add the answer here so that it formats correctly and maybe others will benefit from it. Basically in this situation we use 32 bits for the image data and what is great is that we are reading raw from memory so there is not yet a Bitmap header to skip because this is just raw color information.

NOTE: Across these 4 bytes we have (from bit 0 - 31) B G R A, which we can verify by using my code:

  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++)));
    }

From the output you will see that the A value is 0 for each pixel because there is no concept of transparency or depth here, which is what we expect.

Also to verify that all we have in the buffer is raw image data and no other data I used this calculation which you may also find of use:

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

Where we divide the value of cbBitmapData by 4 because it is a count of the bytes, and as aforementioned for each pixel we have a width of 4 bytes (32-bit DWORDS in actual fact because the length of a byte is not always strictly uniform across hardware apparently!?). We compare this to the image width multiplied by its height. They are equal and thus we have just pixel color information in the buffer.

Hope this helps someone.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文