Course Ipcis: Image Processing With C# Chapter C2: The Complete Code of The Histogram Project
Course Ipcis: Image Processing With C# Chapter C2: The Complete Code of The Histogram Project
System;
System.Drawing;
System.Drawing.Imaging;
System.Windows.Forms;
2
void MenuFileExit( object obj, EventArgs ea )
{ Application.Exit(); }
protected override void OnMouseMove( MouseEventArgs e )
{ if ( e.Button == MouseButtons.None ) return;
if ( !histo_r.Contains( e.X, e.Y ) ) return;
if ( bmp == null ) return;
Byte threshold = (Byte)(e.X - histo_r.X);
/*
//Version 1 (no pointers but slow)***************************************
for ( Int32 i=0; i < bmp.Height; y++ )
for ( Int32 x=0; x < bmp.Width; x++ )
{ if ( grayarray[y ,x] > threshold )
bmp_binary.SetPixel( x, y, Color.White );
else bmp_binary.SetPixel( x, y, Color.Black );
}
//End of Version 1 ******************************************************
*/
/*
//Version 2 (fast pointers creating a memory wasting 32-bit binary image)*
unsafe
{ //lock bmp_binary from being shifted in memory by the garbage collector
binaryData = bmp_binary.LockBits( new Rectangle( 0,0,bmp.Width,bmp.Height ),
ImageLockMode.WriteOnly, PixelFormat.Format32bppRgb );
//Byte* p1fix, p1run = fixed + running pointers to grayarray = input image
UInt32* p2fix, p2run; //fixed + running pointers to binaryData = output image
fixed ( Byte* p1fix = grayarray )
// lock grayarray in memory
{ Byte* p1run = p1fix;
// running pointer to grayarray
p2fix = (UInt32*)binaryData.Scan0; // pointer to output image
for ( int y=0; y < bmp.Height; y++ )
{ p2run = p2fix + y * bmp.Width; //p2run points to first byte in row y
for ( int x=0; x < bmp.Width; x++ )
{ if ( *p1run++ > threshold ) *p2run++ = 0xFFFFFF; // white
else
*p2run++ = 0;
// black
} // end of for x
}
// end of for y
}
// end of fixed, end of p1fix, unlock grayarray
bmp_binary.UnlockBits( binaryData ); //end of p2fix, unlock bmp_binary
} // end of unsafe
//End of Version 2 ******************************************************
*/
//Version 3 (fast pointers creating a 1-bit binary image)****************
unsafe
{ //lock bmp_binary from being shifted in memory by the garbage collector
binaryData = bmp_binary.LockBits( new Rectangle( 0,0,bmp.Width,bmp.Height ),
ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed );
Byte* p2fix, p2row, p2run;
// pointers to binaryData = output image
fixed ( Byte* p1fix = grayarray ) // lock grayarray = input image in memory
{ Byte* p1run = p1fix;
// running pointer to grayarray
p2fix = (byte*)binaryData.Scan0; // pointer to output image
for ( int y=0; y < bmp.Height; y++ )
{ p2row = p2fix + y * binaryData.Stride; //p2row points to first byte in row y
for ( int x=0; x < bmp.Width; x++ )
{ p2run = p2row + x / 8;
if ( *p1run++ > threshold ) *p2run |= ORmask[ x % 8 ];//set
1 bit
else
*p2run &= ANDmask[ x % 8 ];//remove 1 bit
} // end of for x
}
// end of for y
}
// end of fixed, end of p1fix, unlock grayarray
bmp_binary.UnlockBits( binaryData ); // end of p2fix, unlock bmp_binary
} // end of unsafe
//End of Version 3 ******************************************************
g = CreateGraphics();
g.DrawImage( bmp_binary, ClientRectangle );
g.DrawImage( bmp_histo, histo_r );
g.DrawLine( rpen, histo_r.X+threshold, histo_r.Y,
histo_r.X+threshold, histo_r.Y+histo_r.Height-1 );
}
protected override void OnMouseUp(MouseEventArgs e)
{ Invalidate(); }
protected override void OnPaint( PaintEventArgs e )
{ if ( bmp == null )
{ e.Graphics.DrawString( "Open an Image File !", Font, bbrush, 0, 0 ); return; }
e.Graphics.DrawImage( bmp, ClientRectangle );
histo_r.X = ClientRectangle.Width - histo_r.Width - 10;
histo_r.Y = ClientRectangle.Height - histo_r.Height - 10;
e.Graphics.DrawImage( bmp_histo, histo_r );
}
}