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(Back image.Widt h, Backimage.Height, System.Drawing.Imaging.Pix elFormat.F ormat32bpp PArgb);
Rectangle rect = new Rectangle(0, 0, bm.Width, bm.Height);
System.Drawing.Imaging.Bit mapData bmData = bm.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppPAr gb);
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.Drawi ng.RotateF lipType.Ro tate90Flip X);
Backimage = bm;
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(Back
Rectangle rect = new Rectangle(0, 0, bm.Width, bm.Height);
System.Drawing.Imaging.Bit
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.Drawi
Backimage = bm;
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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?