嵌套Parallel.For循环

时间:2017-10-15 10:27:37

标签: c# image-processing parallel-processing task-parallel-library

我想将常规for循环转换为Parallel.For循环。

此 -

for (int i = 0; i < bitmapImage.Width; i++)
{
    for (int x = 0; x < bitmapImage.Height; x++)
    {
        System.Drawing.Color oc = bitmapImage.GetPixel(i, x);
        int gray = (int)((oc.R * 0.3) + (oc.G * 0.59) + (oc.B * 0.11));
        System.Drawing.Color nc = System.Drawing.Color.FromArgb(oc.A, gray, gray, gray);
        bitmapImage.SetPixel(i, x, nc);
    }
}

进入 -

Parallel.For(0, bitmapImage.Width - 1, i =>
{
    Parallel.For(0, bitmapImage.Height - 1, x =>
    {
        System.Drawing.Color oc = bitmapImage.GetPixel(i, x);
        int gray = (int)((oc.R * 0.3) + (oc.G * 0.59) + (oc.B * 0.11));
        System.Drawing.Color nc = System.Drawing.Color.FromArgb(oc.A, gray, gray, gray);
        bitmapImage.SetPixel(i, x, nc);
    });
});

失败并显示消息 -

  

对象目前正在其他地方使用。

因为多个线程试图访问非线程安全的资源,所以

位于下面一行。知道我怎么能做这个工作吗?

System.Drawing.Color oc = bitmapImage.GetPixel(i, x);

1 个答案:

答案 0 :(得分:1)

这不是一个干净的解决方案,看看你想要达到的目标。最好是一次性获取所有像素,然后在并行处理它们。

我个人使用的替代方案,并且显着改善了性能,是使用不安全的函数进行此转换以输出灰度图像。

public static byte[] MakeGrayScaleRev(byte[] source, ref Bitmap bmp,int Hei,int Wid)
        {            
            int bytesPerPixel = 4;   

            byte[] bytesBig = new byte[Wid * Hei]; //create array to contain bitmap data with padding

            unsafe
            {

                int ic = 0, oc = 0, x = 0;
                //Convert the pixel to it's luminance using the formula:
                // L = .299*R + .587*G + .114*B
                //Note that ic is the input column and oc is the output column                  
                for (int ind = 0, i = 0; ind < 4 * Hei * Wid; ind += 4, i++)
                {                        
                    int g = (int)
                            ((source[ind] / 255.0f) *
                            (0.301f * source[ind + 1] +
                             0.587f * source[ind + 2] +
                            0.114f * source[ind + 3]));
                    bytesBig[i] = (byte)g;
                }    
            }

            try
            {

                bmp = new Bitmap(Wid, Hei, PixelFormat.Format8bppIndexed);

                bmp.Palette = GetGrayScalePalette();

                Rectangle dimension = new Rectangle(0, 0, Wid, Hei);
                BitmapData picData = bmp.LockBits(dimension, ImageLockMode.ReadWrite, bmp.PixelFormat);


                IntPtr pixelStartAddress = picData.Scan0;

                Marshal.Copy(forpictures, 0, pixelStartAddress, forpictures.Length);

                bmp.UnlockBits(picData);

                return bytesBig;

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);

                return null;

            }

        }

它获取输入图像的所有像素的字节数,其高度和宽度,并输出计算的灰度数组,并在ref Bitmap bmp中输出灰度位图。