因此,我用GUI、C#制作了一些简单的图像处理程序。例如,我想更改HSV颜色模型中的图像颜色,将每个像素从RGB转换回来。
我的程序根据用户的选择加载一些图片,并使用其Graphics上下文将其显示在窗体的一个面板中。然后用户可以通过移动滚动条、点击按钮、选择一些图像区域等方式来处理这张图片。当他这样做时,我需要实时逐像素更改所有图片。所以,我写了一些类似的东西:
for (int x = 0; x < imageWidth; x++)
for (int y = 0; y < imageHeight; y++)
Color c = g.GetPixel(x, y);
c = some_process_color_function_depending_on_user_controls(c);
g.SetPixel(x, y)
即使我在内存中(而不是在屏幕上)使用Graphics,函数GetPixel和SetPixel的工作速度也很慢(所以,由于我的程序工作速度很慢,我对它进行了分析,并解释说这两个函数最多会减慢我的程序)。所以,我不能在用户移动滑块或选中复选框的几分钟内处理大图片。
请帮忙!我能做些什么来使我的程序更快?我不同意使用其他第三方图形库或更改编程语言!
是的,Get/SetPixel函数非常慢。请改用Bitmap.LockBits()/UlockBits(。它返回原始位数据供您操作。
来自msdn参考:
private void LockUnlockBitsExample(PaintEventArgs e)
{
// Create a new bitmap.
Bitmap bmp = new Bitmap("c:\fakePhoto.jpg");
// Lock the bitmap's bits.
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData =
bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
bmp.PixelFormat);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
// This code is specific to a bitmap with 24 bits per pixels.
int bytes = bmp.Width * bmp.Height * 3;
byte[] rgbValues = new byte[bytes];
// Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
// Set every red value to 255.
for (int counter = 2; counter < rgbValues.Length; counter+=3)
rgbValues[counter] = 255;
// Copy the RGB values back to the bitmap
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
// Unlock the bits.
bmp.UnlockBits(bmpData);
// Draw the modified image.
e.Graphics.DrawImage(bmp, 0, 150);
}