Link to home
Start Free TrialLog in
Avatar of raw_enha
raw_enha

asked on

Faster Imaging Processing Width and Level in C#

i got this block of code that adjust the width and level of a grayscale image.  
The problem is that it is extremely slow, can any expert give me any tips to make it faster?
I'm trying to make the process in real time.

Backimage is where I store the original image in the buffer.

int range1 = ImageInfoObj.MaxPixel;
            int range0 = ImageInfoObj.MinPixel;
            int[] pixels = ImageInfoObj.GetPixels();
            if (ImageInfoObj != null)
            {
                ImgWidth += distX * (range1 - range0 + 1) / ImageDrwPanel.Width;
                ImgLevel -= distY * (range1 - range0 + 1) / ImageDrwPanel.Height;
                if (ImgWidth <= 0) ImgWidth = 0;
                if (ImgWidth > range1 - range0 + 1) ImgWidth = range1 - range0 + 1;
                if (ImgLevel < range0) ImgLevel = range0;
                if (ImgLevel > range1) ImgLevel = range1;

            }
            System.Drawing.Bitmap bm = new System.Drawing.Bitmap(Backimage.Width, Backimage.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
            Rectangle rect = new Rectangle(0, 0, bm.Width, bm.Height);
            System.Drawing.Imaging.BitmapData bmData = bm.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppPArgb);
            int stride = bmData.Stride;
            System.IntPtr Scan0 = bmData.Scan0;
            int index = -1;
            unsafe
            {
                byte* p = (byte*)(void*)Scan0;
                int nOffset = stride - bm.Width * 4;
                for (int y = 0; y < bm.Height; ++y)
                {
                    for (int x = 0; x < bm.Width; ++x)
                    {
                        int color = pixels[++index];
                        if (color < (ImgLevel - ImgWidth / 2))
                        {
                            color = 0;
                        }
                        else if (color > (ImgLevel + ImgWidth / 2))
                        {
                            color = 255;
                        }
                        else
                        {
                            if (ImgWidth == 0)
                            {
                                color = 0;
                            }
                            else
                            {
                                color = 255 * (color - ImgLevel + ImgWidth / 2) / ImgWidth;
                            }
                        }
                        p[2] = (byte)color;
                        p[1] = (byte)color;
                        p[0] = (byte)color;
                        p[3] = (byte)255;

                        p += 4;
                    }
                    p += nOffset;
                }
            }
            bm.UnlockBits(bmData);
            bm.RotateFlip(System.Drawing.RotateFlipType.Rotate90FlipX);
            Backimage = bm;
SOLUTION
Avatar of _TAD_
_TAD_

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of AlexFM
AlexFM

1. Replace 32bppPArgb bitmap with true graylevel bitmap which has one byte per pixel.

2. int color = pixels[++index];
This requires calculating of pixel offset. Replace this with unsafe pointer which is incremented in every iteration.

3. Make some math optimizations. For example:

if (color < (ImgLevel - ImgWidth / 2))
ImgLevel - ImgWidth / 2 can be calculated once before loop. However, I beleive that JIT compiler optimizes this.

if (ImgWidth == 0)
Is this test really necessary?
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial