This chapter shows you how to write text and draw graphics on the live video images.
The source code for the C# version of this sample program can be found in the samples\C# *\Creating an Overlay in your My Documents/IC Imaging Control 3.5 directory.
First of all, create a new project and add IC Imaging Control to the form as shown in the FirstSteps chapter.
Then, insert three new buttons to your form and name them cmdSelectDevice, cmdLiveVideo and cmdImageSetting. Label the buttons Device, Start and Settings respectively. These buttons will be used to select the video capture device, start and stop the live video and open the image settings dialog.
Now, implement the handler methods for the three buttons:
[C#]
private void cmdDevice_Click( object sender, EventArgs e ) { cmdStartStop.Text = "Start"; bool wasLive = icImagingControl1.LiveVideoRunning; if( wasLive ) icImagingControl1.LiveStop(); icImagingControl1.ShowDeviceSettingsDialog(); if( icImagingControl1.DeviceValid ) { if( wasLive ) { icImagingControl1.LiveStart(); cmdStartStop.Text = "Stop"; } cmdStartStop.Enabled = true; cmdSettings.Enabled = true; } }
[C#]
private void cmdStartStop_Click( object sender, EventArgs e ) { if( icImagingControl1.LiveVideoRunning ) { icImagingControl1.LiveStop(); cmdStartStop.Text = "Start"; } else { if( icImagingControl1.DeviceValid ) { icImagingControl1.LiveStart(); cmdStartStop.Text = "Stop"; } } }
[C#]
private void cmdSettings_Click( object sender, EventArgs e ) { if( icImagingControl1.DeviceValid ) { icImagingControl1.ShowPropertyDialog(); } }
Run the program: You should be able to select a video capture device and see the live video.
IC Imaging Control provides a special object for drawing and writing on the live video. The object is called OverlayBitmap.
The OverlayBitmap object contains a bitmap, which has the same size as the video format, or the size of a frame filter that transforms the image data before the overlay bitmap is applied. An application can draw text and graphics on this overlay bitmap. The overlay bitmap is copied to each sample of the video. A dropout color can be specified to determine, which pixels of the overlay bitmap are transparent and therefore not copied to the live video.
The overlay bitmap can only be used, if ICImagingControl.LiveStart has been called at least once after the video format has been changed. It is only visible, if the live video is running.
Since version 3.0, IC Imaging Control allows you to select whether the overlay is drawn on live video, on grabbed and recorded images, or both.
You can use ICImagingControl.OverlayBitmapPosition to set an ORed combination of PathPositions values that specify the path positions at which overlay bitmap objects are inserted.
Enabling the overlay bitmap is a two-step process: The OverlayBitmapPosition has to be set before starting live mode and determines, at which path positions overlay operations are possible. OverlayBitmap.Enable enables or disables the application of a specific overlay bitmap while live mode is running.
To access one of the 3 OverlayBitmap objects, use ICImagingControl.OverlayBitmapAtPath. The parameter of that property selects the position of the OverlayBitmap that is accessed.
The ICImagingControl.OverlayBitmap property returns the OverlayBitmap for the device path.
A program can draw on any of the overlay bitmaps once live mode has been prepared or started. Live mode has to be prepared first, because the actual size and color format of the overlay bitmaps can depend on frame filters, thus it is impossible to determine the formats before.
The ICImagingControl.LivePrepared event is raised when live mode has been successfully prepared. Implement an event handler that draws several graphics on the 3 overlay bitmaps:
[C#]
private void icImagingControl1_LivePrepared( object sender, EventArgs e ) { if( icImagingControl1.DeviceValid ) { if( (icImagingControl1.OverlayBitmapPosition & PathPositions.Device) != 0 ) { SetupOverlay( icImagingControl1.OverlayBitmapAtPath[PathPositions.Device] ); // Display a coordinate system on the device overlay DrawCoordinatesystem( icImagingControl1.OverlayBitmapAtPath[PathPositions.Device] ); // Draw overlay info box DrawOverlayInfo( icImagingControl1.OverlayBitmapAtPath[PathPositions.Device] ); } if( (icImagingControl1.OverlayBitmapPosition & PathPositions.Sink) != 0 ) { SetupOverlay( icImagingControl1.OverlayBitmapAtPath[PathPositions.Sink] ); // Draw overlay info box DrawOverlayInfo( icImagingControl1.OverlayBitmapAtPath[PathPositions.Sink] ); } if( (icImagingControl1.OverlayBitmapPosition & PathPositions.Display) != 0 ) { SetupOverlay( icImagingControl1.OverlayBitmapAtPath[PathPositions.Display] ); // Load a bitmap file and display it on the display overlay ShowBitmap( icImagingControl1.OverlayBitmapAtPath[PathPositions.Display] ); // Draw overlay info box DrawOverlayInfo( icImagingControl1.OverlayBitmapAtPath[PathPositions.Display] ); } } }
The SetupOverlay sub is used to initialize each of the 3 overlays. It is called after live mode has been started.
[C#]
private void SetupOverlay( TIS.Imaging.OverlayBitmap ob ) { // Enable the overlay bitmap for drawing. ob.Enable = true; // Set magenta as dropout color. ob.DropOutColor = Color.Magenta; // Fill the overlay bitmap with the dropout color. ob.Fill( ob.DropOutColor ); // Print text in red. ob.FontTransparent = true; ob.DrawText( Color.Red, 10, 10, "IC Imaging Control 3.2" ); }
The overlay is enabled by calling OverlayBitmap.Enable, and a text is displayed in the upper left hand corner of the bitmap. The sub also sets a dropout color.
The OverlayBitmap.DropOutColor property of the OverlayBitmap object determines, which pixel color is transparent on the live video. Each pixel that has the dropout color is not copied to the live video. It defaults to black. For this reason, the background of the text written above is transparent. The FontBackColor property of the OverlayBitmap object is set to black as default too.
In order to be able to use black color in the overlay, we change OverlayBitmap.DropOutColor to another color, for example magenta (RGB(255,0,255)). If the application is started, only a black image with our text can be seen. The image is black, because the overlay bitmap is black and the dropout color has been changed to magenta. Therefore, the overlay bitmap must be filled with magenta. The method OverlayBitmap.Fill does this for us. When the dropout color is changed, the text background is visible as a solid black rectangle. To hide this, the property OverlayBitmap.FontTransparent can be set to True.
In the next step, we are going to draw a coordinate plane, consisting of lines and labels. To do this, we are going to use the DrawLine and DrawText methods of the OverlayBitmap object. Additionally, we are going to change the font used to write the labels.
We are going to implement a new sub called DrawCoordinatesystem. We want to use an 8 dpi Arial font for the labels. To achieve this, a new StdFont object Font must be created. This object has font properties like font name, font size and other font attributes. Before changing the font, we save the current font in order to be able to restore it after we have completed the coordinate plane.
The Font property of the OverlayBitmap object receives the StdFont object. Now, the new font is used for all following OverlayBitmap.DrawText calls.
The complete sub that draws the coordinate plane is implemented as follows:
[C#]
private void DrawCoordinatesystem( TIS.Imaging.OverlayBitmap ob ) { // Calculate the center of the video image. int Col = GetVideoDimension().Width / 2; int Row = GetVideoDimension().Height / 2; Font OldFont = ob.Font; ob.Font = new Font( "Arial", 8 ); ob.DrawLine( Color.Red, Col, 0, Col, GetVideoDimension().Height ); ob.DrawLine( Color.Red, 0, Row, GetVideoDimension().Width, Row ); for( int i = 0; i < Row; i += 20 ) { ob.DrawLine( Color.Red, Col - 5, Row - i, Col + 5, Row - i ); ob.DrawLine( Color.Red, Col - 5, Row + i, Col + 5, Row + i ); if( i > 0 ) { ob.DrawText( Color.Red, Col + 10, Row - i - 7, string.Format( "{0}", i / 10 ) ); ob.DrawText( Color.Red, Col + 10, Row + i - 7, string.Format( "{0}", -i / 10 ) ); } } for( int i = 0; i < Col; i += 20 ) { ob.DrawLine( Color.Red, Col - i, Row - 5, Col - i, Row + 5 ); ob.DrawLine( Color.Red, Col + i, Row - 5, Col + i, Row + 5 ); if( i > 0 ) { ob.DrawText( Color.Red, Col + i - 5, Row - 17, string.Format( "{0}", i / 10 ) ); ob.DrawText( Color.Red, Col - i - 10, Row - 17, string.Format( "{0}", -i / 10 ) ); } } ob.Font = OldFont; }
To display the current time on the live video, a timer is inserted in the form. It is called timer1 by default and its timer interval is set to 1000 milliseconds in the property window. The timer event handler sub is called Timer1_timer. The current time is displayed in the lower right hand corner. It has a white font with a black background. Furthermore, it has its own font. Therefore, a StdFont object must be created and used, as described above. The property OverlayBitmap.FontTransparent is set to False and OverlayBitmap.FontBackColor is set to black (RGB 0 0 0).
[C#]
private void timer1_Tick( object sender, EventArgs e ) { TIS.Imaging.OverlayBitmap ob = icImagingControl1.OverlayBitmapAtPath[TIS.Imaging.PathPositions.Device]; if( icImagingControl1.LiveVideoRunning ) { // Save the current font. Font OldFont = ob.Font; ob.Font = new Font( "Arial", 14, FontStyle.Bold ); // Draw the time in the lower left corner of the video window. int Col = GetVideoDimension().Width - 81; int Row = GetVideoDimension().Height - 20; // Setup the background color and drawing mode. ob.FontTransparent = false; ob.FontBackColor = Color.Black; // Draw the current time with white color. ob.DrawText( Color.White, Col, Row, DateTime.Now.ToString( "T" ) ); // Restore the previously used font. ob.Font = OldFont; } }
IC Imaging Control provides an OverlayUpdate event. This event is called after a new frame has been delivered from the video capture device. Therefore, it is possible to insert individual information on to each frame (i.e. frame counter).
The OverlayUpdate sub in the example counts the frames in the variable FrameCount. The frame counter is used to draw a growing triangle. If the frame counter is greater than 25, it is reset to 0 and the triangle is deleted. Therefore, if a solid rectangle of the same size is drawn over the triangle. The color of the rectangle must be set to the DropOutColor to make it transparent. The method DrawSolidRect provides this functionality.
The OverlayUpdate event handler is implemented as follows:
[C#]
private void icImagingControl1_OverlayUpdate( object sender, TIS.Imaging.ICImagingControl.OverlayUpdateEventArgs e ) { TIS.Imaging.OverlayBitmap ob = e.overlay; var info = icImagingControl1.DriverFrameDropInformation; int frameCount = (int)info.FramesDelivered; int lineIndex = frameCount % 25; if( lineIndex == 0 ) { ob.DrawSolidRect( ob.DropOutColor, 10, GetVideoDimension().Height - 70, 62, GetVideoDimension().Height - 9 ); } ob.DrawLine( Color.Yellow, lineIndex * 2 + 10, GetVideoDimension().Height - 10, lineIndex * 2 + 10, GetVideoDimension().Height - 10 - lineIndex ); // Print the current frame number: // Set the background color to the current dropout color // and make the font opaque. ob.FontBackColor = ob.DropOutColor; ob.FontTransparent = false; // Save the current font. Font OldFont = ob.Font; // Draw the text. ob.Font = new Font( "Arial", 8 ); ob.DrawText( Color.Yellow, 70, GetVideoDimension().Height - 19, frameCount.ToString() ); // Restore the previously used font. ob.Font = OldFont; }
A new sub ShowBitmap is implemented to demonstrate how to render a bitmap onto the overlay bitmap. It uses the method OverlayBitmap.GetGraphics to retrieve a .NET Graphics object that can be used to draw on the overlay bitmap.
[C#]
private void ShowBitmap( TIS.Imaging.OverlayBitmap ob ) { try { // We have added the hardware.bmp as a resource to the project, so that we can easily access it here var bmp = Creating_an_Overlay.Properties.Resources.hardware; // Calculate the column to display the bitmap in the // upper right corner of Imaging Control. int col = GetVideoDimension().Width - 5 - bmp.Width; // Retrieve the Graphics object of the OverlayBitmap. Graphics g = ob.GetGraphics(); // Draw the image g.DrawImage( bmp, col, 5 ); // Release the Graphics after drawing is finished. ob.ReleaseGraphics( g ); } catch( Exception Ex ) { MessageBox.Show( "File not found: " + Ex.Message ); } }
The end user of our example program can control which of the 3 overlay bitmaps are drawn on the live video. To change the PathPositions, the following helper sub is used:
[C#]
private void EnableOverlayBitmapAtPath( PathPositions pos, bool enabled ) { bool wasLive = icImagingControl1.LiveVideoRunning; if( wasLive ) icImagingControl1.LiveStop(); PathPositions oldPos = icImagingControl1.OverlayBitmapPosition; if( enabled ) icImagingControl1.OverlayBitmapPosition = oldPos | pos; else icImagingControl1.OverlayBitmapPosition = oldPos & ~pos; if( wasLive ) icImagingControl1.LiveStart(); }
This sub enables or disables the overlay at a specified path position.
An application can decide whether it wants a color or grayscale overlay. The OverlayBitmap.ColorMode property can be used to select one of the available color modes:
When the format of the image data stream does not match the overlay bitmap color mode, the image data is automatically converted.