Click here to Skip to main content
15,882,209 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I created some methods and tested that they worked, the only problem was GUI not responding.

So i created a new class, copy/pasted in the methods and made it run in a new thread.

Now the problem was solved, GUI was responding correctly but now methods take 2-3 times longer to complete.

I hope someone has a solution.

static class ColorSmoother
    {
        private static bool _run;
        private static byte _stepSize;
        private static Thread _worker;
        #region Events
        public delegate void ProgressEventHandler(Bitmap bitmap);
        public static event ProgressEventHandler Starting;
        public static event ProgressEventHandler Step;
        public static event ProgressEventHandler Done; 
        #endregion
        static ColorSmoother()
        {
            _worker = new Thread(new ParameterizedThreadStart(Work));
            _worker.Name = "ColorSmoother - Worker Thread";
            _worker.Priority = ThreadPriority.Highest;
        }
        public static byte StepSize
        {
            get { return _stepSize; }
            set { _stepSize = value; }
        }
        public static bool Run
        {
            get { return _run; }
            set { _run = value; }
        }
        static void Work(object param)
        {
            Bitmap tempBitmap = (Bitmap) param;
            param = null;
            Run = true;
            if (Starting != null)
                Starting(tempBitmap);
            int x,y, width = tempBitmap.Width, height = tempBitmap.Height;
            Color newColor = Color.DimGray,oldColor;
            for (x = 0; x < width; x++)
            {
                for (y = 0; y < height; y++)
                {
                    if (!Run)
                    {
                        tempBitmap.Dispose();
                        return;
                    }
                    oldColor = tempBitmap.GetPixel(x, y);
                    newColor = GetNewColor(oldColor);
                    tempBitmap.SetPixel(x, y, newColor);
                    if (Step != null)
                        Step(tempBitmap);
                }
            }
            if (Done != null)
                Done(tempBitmap);
            tempBitmap.Dispose();
        }
        internal static void SmoothImage(Bitmap newBitmap)
        {
            _worker = new Thread(new ParameterizedThreadStart(Work));
            _worker.Start(newBitmap);
        }
        private static Color GetNewColor(Color oldColor)
        {
            Color newColor;
            byte r = FindColorGroup(oldColor.R);
            byte g = FindColorGroup(oldColor.G);
            byte b = FindColorGroup(oldColor.B);
            newColor = Color.FromArgb(r, g, b);
            return newColor;
        }
        private static byte FindColorGroup(int color)//148
        {
            int groupValue = 0;
            while (groupValue + StepSize < color)//97
            {
                groupValue += StepSize;
            }
            if (color - groupValue > (groupValue + StepSize) - color)
                groupValue += StepSize;
            if (groupValue > 255)
                groupValue = 255;

            return (byte)groupValue;
        }
    }
Posted

1 solution

Well, threading has its overhead, but there are other problems which compromise your performance.

Never use GetPixel/SetPixel, it's too slow! (Unless you need just 1 or 2-3 pixels :-).) If this is System.Drawing.Bitmap, use LockBits/UnlockBits instead. Find a code sample here:
http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx[^].

You seemingly ignore the various Pixel Formats, this is unsafe, see PixelFormat.

ParameterizedThreadStart makes no sense! If forces you into unsafe practice of type case. You can create a thread wrapper and pass its "this" reference instead. Please see my code sample here:
How to pass ref parameter to the thread[^].

See my past answers on using threads with UI:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

Good luck,
—SA
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900