Click here to Skip to main content
14,384,304 members
Rate this:
Please Sign up or sign in to 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

Rate this:
Please Sign up or sign in to vote.

Solution 1

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
   

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




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100