我正在努力优化我正在研究的程序,该程序当前使用锁定位读取字节数据,但使用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;
答案 0 :(得分: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数组中获得所需的值,并可以开始操作这些