3

我正在优化我正在处理的程序,该程序当前使用锁定位读取字节数据,但使用 setPixel 写入像素数据。那么我如何实际修改我正在读取的像素数据呢?如果我尝试设置 pp、cp 或 np,该方法将不起作用(因为它循环并需要 pp、cp 和 np 来表示像素数据),所以我完全糊涂了。我是否需要将像素数据写入 byte[] 并对其进行操作,还是什么?

这是一个代码示例:

BitmapData data = img.LockBits(new Rectangle(0, 0, img.Width, img.Height),
    ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

int scaledPercent = (int)(Math.Round(percentageInt * 255)) - 47;
Debug.WriteLine("percent " + scaledPercent);
unsafe
{
    Debug.WriteLine("Woah there, unsafe stuff");
    byte* prevLine = (byte*)data.Scan0;
    byte* currLine = prevLine + data.Stride;
    byte* nextLine = currLine + data.Stride;

    for (int y = 1; y < img.Height - 1; y++)
    {
        byte* pp = prevLine + 3;
        byte* cp = currLine + 3;
        byte* np = nextLine + 3;
        for (int x = 1; x < img.Width - 1; x++)
        {
            if (IsEdgeOptimized(pp, cp, np, scaledPercent))
            {
                //Debug.WriteLine("x " + x + "y " + y);
                img2.SetPixel(x, y, Color.Black);
            }
            else
            {
                img2.SetPixel(x, y, Color.White);
            }
            pp += 3; cp += 3; np += 3;
        }
        prevLine = currLine;
        currLine = nextLine;
        nextLine += data.Stride;
    }
}
img.UnlockBits(data);
pictureBox2.Image = img2;
4

1 回答 1

5

与将原始位作为数组获取相比,SetPixel 使用起来很慢。看起来你正在做某种边缘检测(?)。MSDN 上的 LockBits 示例 ( http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx ) 展示了如何获取原始数组并使用它,将结果保存回原始图像。

该示例的有趣之处在于使用 Marshal.copy 复制指针的字节:

        // Get the address of the first line.
        IntPtr ptr = bmpData.Scan0;

        // Declare an array to hold the bytes of the bitmap. 
        int bytes  = Math.Abs(bmpData.Stride) * bmp.Height;
       byte[] rgbValues = new byte[bytes];

        // Copy the RGB values into the array.
        System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);

现在您在 rgbValues 数组中拥有了所需的值,并且可以开始操作这些值

于 2013-09-04T17:45:09.127 回答