【问题标题】:How to process image pixel-by-pixel with WinAPI in a FAST WAY?如何使用 WinAPI 以快速的方式逐像素处理图像?
【发布时间】:2012-09-17 21:30:08
【问题描述】:

所以,我用 GUI、C# 制作了一些简单的图像处理程序。例如,我想在 HSV 颜色模型中更改图像颜色,将每个像素从 RGB 转换回来。

我的程序根据用户的选择加载一些图片,并使用其图形上下文在表单的一个面板中显示它。然后用户可以通过移动滚动条、单击按钮、选择某些图像区域等来处理这张图片。当他这样做时,我需要实时逐像素更改所有图片。所以,我写了这样的东西:

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)

即使我在内存中(不在屏幕上)使用图形,GetPixel 和 SetPixel 函数的工作速度也很慢(所以,由于我的程序运行速度很慢,我对其进行了分析,并解释说这两个函数正在减慢我的速度最多程序)。因此,当用户移动滑块或选中复选框时,我无法在一段时间内处理大图片。

请帮忙!我该怎么做才能让我的程序更快?我不同意使用其他第三方库进行图形或更改编程语言!

【问题讨论】:

  • +1 用于使用分析器,很好!

标签: c# .net windows winapi graphics


【解决方案1】:

是的,Get/SetPixel 函数非常慢。请改用Bitmap.LockBits() / UnlockBits()。它返回原始位数据供您操作。

来自 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);

}

【讨论】:

  • @Abzac 如果速度太慢,您可以查看 XNA 或托管 directx。
  • 您也许可以使用不安全的代码块来提高性能(尽管我不知道这是否会节省大量资金)。 bobpowell.net/lockingbits.htm
  • LockBits 等绝对是正确的方法。我用它来处理和显示相机的实时图像。
猜你喜欢
  • 2016-12-18
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 2011-08-17
  • 2021-02-10
  • 1970-01-01
相关资源
最近更新 更多