使用parallel.for访问图像的每个像素

时间:2015-08-19 09:47:22

标签: c# image asynchronous parallel-processing pixel

所以,我正在开发一个C#项目,它应该将图像逐像素复制到另一个图像变量中。我编写了代码并且它可以正常工作,但它有点太慢了。现在我试图使代码与Parallel.For异步工作,但我正在努力锁定在循环中更改的变量,它总是抛出异常。

所以,这是我的初始代码(我知道这个程序没有多大意义,但这只是一个简单的例子):

Bitmap loadedImage = new Bitmap(filename);
var newImage = new Bitmap(loadedImage.Width, loadedImage.Height);

Color color = new Color();
byte r, g, b;

for (int i = 0; i < loadedImage.Height; i++)
{
    for (int j = 0; j < loadedImage.Width; j++)
    {
        color = loadedImage.GetPixel(j, i);
        r = color.R;
        g = color.G;
        b = color.B;

        newImage.SetPixel(j, i, Color.FromArgb(r, g, b));
    }
}

如果有人帮助我让程序异步工作,我真的很感激。

1 个答案:

答案 0 :(得分:0)

基本上对于数据集的并行应该足够大 - 否则上下文切换的额外成本会使事情变慢,而不是更快。

此外,lockbits将比使用GetPixel获得更快的速度。

也就是说,实施非常简单:

Bitmap loadedImage = new Bitmap(filename); 
var newImage = new Bitmap(loadedImage.Width, loadedImage.Height);

// don't create variables here...
Parallel.For(0, loadedImage.Height, (i) =>
    {
        for (int j = 0; j < loadedImage.Width; j++)
        {
            // but here -- that's better for a lot of reasons.

            var color = loadedImage.GetPixel(j, i);
            var r = color.R;
            var g = color.G;
            var b = color.B;

            newImage.SetPixel(j, i, Color.FromArgb(r, g, b));                    
        }
    });

只要数据没有重叠,这就行了。在我的情况下,没有。

PS:我过去一直在处理照片和Parallel.For,并发现在大多数情况下,它只会减慢速度,而不是让它变得更快。 Lockbits和不安全的代码真的是最佳选择。