c# - 使用 C# 5.0 进行并行图像处理

标签 c# image-processing asynchronous bitmap async-await

我正在尝试使用 C# 使用相同的旧 GDI 技术进行一些图像处理,使用嵌套的 for 循环迭代每个像素,然后对该(位图)图像使用 GetPixel 和 SetPixel 方法。

我已经使用指针方法得到了相同的结果(使用不安全的上下文),但我现在正在尝试使用老式的获取/设置像素方法来处理我的位图...

    Bitmap ToGrayscale(Bitmap source)
    {
        for (int y = 0; y < source.Height;y++ )
        {
            for (int x = 0; x < source.Width; x++)
            {
                Color current = source.GetPixel(x, y);
                int avg = (current.R + current.B + current.G) / 3;
                Color output = Color.FromArgb(avg, avg, avg);
                source.SetPixel(x, y, output);
            }
        }
        return source;
    }

考虑到上面代码的性能......需要太多时间才能完成,同时让用户等待 1800x1600 图像完成处理。

所以我认为我可以使用我们使用 HLSL 的技术,为每个像素运行一个单独的函数(像素着色器引擎(正如我所认为的)在 GPU 上复制返回 float4(颜色)的函数数千次进行并行处理)。

因此,我尝试为每个像素运行一个单独的任务(函数),将这些任务变量放入列表中,并将“等待”放入 List.ToArray() 中。但我未能做到这一点,因为每个新任务都“等待”在下一个任务运行之前完成。

我想为每个像素调用一个新任务来运行它:

                Color current = source.GetPixel(x, y);
                int avg = (current.R + current.B + current.G) / 3;
                Color output = Color.FromArgb(avg, avg, avg);
                source.SetPixel(x, y, output);

最终我得到了一个异步非阻塞代码,但不是并行的...... 大家有什么建议吗?

最佳答案

GetPixelSetPixel 可能是这里的主要瓶颈。

我建议使用Bitmap.LockBits,而不是尝试并行化它。更有效地处理解析。

话虽如此,您可以通过以下方式并行化当前版本:

Bitmap ToGrayscale(Bitmap source)
{
    Parallel.For(0, source.Height, y =>
    {
        for (int x = 0; x < source.Width; x++)
        {
            Color current = source.GetPixel(x, y);
            int avg = (current.R + current.B + current.G) / 3;
            Color output = Color.FromArgb(avg, avg, avg);
            source.SetPixel(x, y, output);
        }
    });

    return source;
}

但是,Bitmap 类不是线程安全的,因此这可能会导致问题。

更好的方法是使用 LockBits,然后直接并行处理原始数据(如上所述)。请注意,我仅并行化外循环(有意),因为这将防止工作项的核心过度饱和。

关于c# - 使用 C# 5.0 进行并行图像处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18369823/

相关文章:

c# - 从 C# 上传到 GDrive

c# - 如何从数据集中获取数据到 gridview?

delphi - 加载 Jpg/Gif/Bitmap 并转换为 Bitmap

asynchronous - Vue JS AJAX 计算属性

c# - 可观察的创建异步

c# - xUnit : Mutiple Assertions or Soft Assert

c# - Gembox 电子表格 C# : It is a way to detect if a cell has border?

python - 区分规则和不规则形状的 Blob

输入图像类型上的 opencv 错误应为 CV_8UC3 或 CV_8UC4

java - Mongodb 异步 java 驱动程序 find()