如何将此方法与Bitmap并行化 [英] How do I parallelize this method with Bitmap

查看:40
本文介绍了如何将此方法与Bitmap并行化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我尝试在本文中并行化序列代码

语言学:C#中的简单实现 [ ^ ]



我知道如何使用Parallel.For,但在这种情况下,我需要在循环内返回值(Bitmap对象)。有3个嵌套和一些if。

下面我发布了序列和修改后的并行代码以及关于该返回的2个错误。



< b>以下是错误:

错误2无法将匿名方法转换为委托类型'System.Action< long,system.threading.tasks.parallelloopstate>'因为某些返回类型在块中不能隐式转换为委托返回类型。



错误1因为'System.Action< long,system.threading.tasks.parallelloopstate>'返回void ,一个return关键字后面不能跟一个对象表达式。



有人可以帮我这个吗?我会非常感激,因为我不知道该怎么办:/





这是原作序列码:



Hi,
I try to parallelize sequence code in this article
Steganography: Simple Implementation in C#[^]

I know how to use Parallel.For, but in this case, I need return value (Bitmap object) inside the loop. There is 3 nested for and some if.
Below I post both sequence and modified parallel code and 2 errors regarding that return.

Here are the errors:
Error 2 Cannot convert anonymous method to delegate type 'System.Action<long,system.threading.tasks.parallelloopstate>' because some of the return types in the block are not implicitly convertible to the delegate return type.

Error 1 Since 'System.Action<long,system.threading.tasks.parallelloopstate>' returns void, a return keyword must not be followed by an object expression.

Can someone help me with this? I would be very grateful, because I don't know what to do with it :/


Here is the original sequence code:

public static Bitmap embedText(string text, Bitmap bmp)
    {
        State s = State.hiding;

        int charIndex = 0;
        int charValue = 0;
        long colorUnitIndex = 0;

        int zeros = 0;

        int R = 0, G = 0, B = 0;

        for (int i = 0; i < bmp.Height; i++)
        {
            for (int j = 0; j < bmp.Width; j++)
            {
                Color pixel = bmp.GetPixel(j, i);

                pixel = Color.FromArgb(pixel.R - pixel.R % 2,
                    pixel.G - pixel.G % 2, pixel.B - pixel.B % 2);

                R = pixel.R; G = pixel.G; B = pixel.B;

                for (int n = 0; n < 3; n++)
                {
                    if (colorUnitIndex % 8 == 0)
                    {
                        if (zeros == 8)
                        {
                            if ((colorUnitIndex - 1) % 3 < 2)
                            {
                                bmp.SetPixel(j, i, Color.FromArgb(R, G, B));
                            }

                            return bmp;
                        }

                        if (charIndex >= text.Length)
                        {
                            s = State.filling_with_zeros;
                        }
                        else
                        {
                            charValue = text[charIndex++];
                        }
                    }

                    switch (colorUnitIndex % 3)
                    {
                        case 0:
                            {
                                if (s == State.hiding)
                                {
                                    R += charValue % 2;

                                    charValue /= 2;
                                }
                            } break;
                        case 1:
                            {
                                if (s == State.hiding)
                                {
                                    G += charValue % 2;

                                    charValue /= 2;
                                }
                            } break;
                        case 2:
                            {
                                if (s == State.hiding)
                                {
                                    B += charValue % 2;

                                    charValue /= 2;
                                }

                                bmp.SetPixel(j, i, Color.FromArgb(R, G, B));
                            } break;
                    }

                    colorUnitIndex++;

                    if (s == State.filling_with_zeros)
                    {
                        zeros++;
                    }
                }
            }
        }

        return bmp;
    }



并修改了并行版本的代码:


And there is modified code to parallel version:

public static Bitmap embedText(string text, Bitmap bmp)
        {
            State s = State.hiding;

            int charIndex = 0;
            int charValue = 0;
            long colorUnitIndex = 0;

            int zeros = 0;

            int R = 0, G = 0, B = 0;

            Parallel.For (0, bmp.Height, delegate(int i)
            {
                Parallel.For (0, bmp.Width, delegate(int j)
                {
                    Color pixel = bmp.GetPixel(j, i);

                    pixel = Color.FromArgb(pixel.R - pixel.R % 2,
                        pixel.G - pixel.G % 2, pixel.B - pixel.B % 2);

                    R = pixel.R; G = pixel.G; B = pixel.B;

                    for (int n = 0; n < 3; n++)
                    {
                        if (colorUnitIndex % 8 == 0)
                        {
                            if (zeros == 8)
                            {
                                if ((colorUnitIndex - 1) % 3 < 2)
                                {
                                    bmp.SetPixel(j, i, Color.FromArgb(R, G, B));
                                }

                                return bmp; return bmp; //In this line is both 2 errors
                            }

                            if (charIndex >= text.Length)
                            {
                                s = State.filling_with_zeros;
                            }
                            else
                            {
                                charValue = text[charIndex++];
                            }
                        }

                        switch (colorUnitIndex % 3)
                        {
                            case 0:
                                {
                                    if (s == State.hiding)
                                    {
                                        R += charValue % 2;

                                        charValue /= 2;
                                    }
                                } break;
                            case 1:
                                {
                                    if (s == State.hiding)
                                    {
                                        G += charValue % 2;

                                        charValue /= 2;
                                    }
                                } break;
                            case 2:
                                {
                                    if (s == State.hiding)
                                    {
                                        B += charValue % 2;

                                        charValue /= 2;
                                    }

                                    bmp.SetPixel(j, i, Color.FromArgb(R, G, B));
                                } break;
                        }

                        colorUnitIndex++;

                        if (s == State.filling_with_zeros)
                        {
                            zeros++;
                        }
                    }
                }
            });

            return bmp;
        }

推荐答案

请不要使用 GetPixel来代替并行化 / SetPixel ;这些方法非常慢,只能用于获取或设置很少的像素。相反,锁定位并在内存中处理它们:

http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.lockbits%28v=vs.110%29.aspx [ ^ ]。



有关代码示例的第一种方法,请参阅文档页面。



-SA
Instead of "parallelizing" the way you do, don't use GetPixel/SetPixel; these methods are prohibitively slow and can only be used to get or set very few pixels. Instead, lock bit and process them in memory:
http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.lockbits%28v=vs.110%29.aspx[^].

See the documentation page for the first of these two methods for code sample.

—SA


这篇关于如何将此方法与Bitmap并行化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆