在绘制像素方法中不清楚不安全的代码

时间:2012-10-06 21:59:46

标签: c# pointers bitmap unsafe writeablebitmap

最近我做了低级图形编程工作(实现光栅图形算法)。 这就是为什么我开始寻找有助于在低抽象级别(甚至使用unsafe代码)上绘制基元(线,矩形,椭圆等)的工具(类)。

我考虑是否应该在 WPF WindowsForms WinAPI 或其他环境中实现我的算法。现在我要尝试 WPF 。我找到了一些如何在位图上绘制像素的示例,但遗憾的是我在理解此代码时遇到了问题(source code from MSDN):

    // The DrawPixel method updates the WriteableBitmap by using 
    // unsafe code to write a pixel into the back buffer. 
    static void DrawPixel(MouseEventArgs e)
    {
        int column = (int)e.GetPosition(i).X;
        int row = (int)e.GetPosition(i).Y;

        // Reserve the back buffer for updates.
        writeableBitmap.Lock();

        unsafe
        {
            // Get a pointer to the back buffer. 
            int pBackBuffer = (int)writeableBitmap.BackBuffer;

            // Find the address of the pixel to draw.
            pBackBuffer += row * writeableBitmap.BackBufferStride;
            pBackBuffer += column * 4;//??

            // Compute the pixel's color. 
            int color_data = 255 << 16; // R
            color_data |= 128 << 8;   // G
            color_data |= 255 << 0;   // B 

            // Assign the color data to the pixel.
            *((int*)pBackBuffer) = color_data;//??
        }

        // Specify the area of the bitmap that changed.
        writeableBitmap.AddDirtyRect(new Int32Rect(column, row, 1, 1));

        // Release the back buffer and make it available for display.
        writeableBitmap.Unlock();
    }
  1. 这条pBackBuffer += column * 4;行是什么?为什么4
  2. *((int*)pBackBuffer) = color_data;是什么意思?我知道来自 C / C ++ 的指针,但是在 C#中有IntPtrint*这一行int pBackBuffer = (int)writeableBitmap.BackBuffer;表明我们可以对待同样intIntPtr对我来说也不清楚。
  3. 我应该使用哪种编程环境? WinAPIWPF或其他?
  4. 如果有人能解释我不安全的代码,我将非常感激。

2 个答案:

答案 0 :(得分:3)

  

1:这是什么pBackBuffer + =列* 4;排队?为什么4?

假设像素是ARGB,则每像素4个字节。由于column是X坐标,因此必须乘以4.

  

2:它是什么((int )pBackBuffer)= color_data;意思?

(int*)pBackBuffer - 将int pBackBuffer的值视为指向int

的指针

*((int*)pBackBuffer) = color_data - 将color_data存储到该指针

IntPtr和int不完全相同。在32位操作系统上运行时IntPtr为32位,在64位操作系统上运行时为64位。 int总是32位。

答案 1 :(得分:0)

根据之前的注释,如果您希望代码同时适用于x64和x86,则使用int而不是IntPtr指向BackBuffer是一个错误。该行应该是......

IntPtr pBackBuffer = (IntPtr)writeableBitmap.BackBuffer;

因为BackBuffer是一个指针,它将根据你的x64或x86改变大小。 &#39; INT&#39;将始终为32位,因此在编译x64

时可能会导致溢出异常