オーバーレイの作成
概要
ライブ表示している画面上にテキストや線などを描く方法について説明しています。 画像ストリームにおけるOverlayBitmapの配置可能ポジションをチェックボックスで切り替えることで、ライブ表示あるいは保存する画像で表示の制御をしています。また、コマンドボタンを使ってカラーもしくはモノクロのどちらで表示するかを選択できます。
サンプルプログラム
Software | IC Imaging Control 3.5, Visual Studio™ 2019 |
---|---|
サンプル(C#) | creating_an_overlay_cs_3.5.zip |
サンプル(VB.NET) | creating_an_overlay_vb_3.5.zip |
実行結果
Visual Studioのプログラム上ではすでにボタンの設置や関数は定義済ですので、IC Imaging Contorl3.5をインストールされていれば、実行ボタンだけですぐにデバッグで動作確認することができます。
画面にあるそれぞれのボタンなどのコントローラの機能は下記の通りです。
[Device]ボタン | デバイスを選択するダイアログ画面を表示 |
---|---|
[Setting]ボタン | デバイスプロパティのダイアログ画面を表示 |
[Stop]ボタン | ライブ表示を停止 |
[Device]チェックボックス | チェックすることでライブ画像でもキャプチャ画像/動画でも表示されます |
[Sink]チェックボックス | チェックすることでキャプチャ画像/動画では表示されますが、ライブ画像では表示されません。 |
[Display]チェックボックス | チェックすることでライブ画像では表示されますが、キャプチャ画像/動画では表示されません。 |
Color Mode | カラーもしくはモノクロのどちらで表示するか切り替えることができます。 |
オーバーレイの下準備
private void Form1_Load( object sender, EventArgs e )
{
//画像ストリームにおけるOverlayBitmapオブジェクトの位置をコントロール
icImagingControl1.OverlayBitmapPosition = TIS.Imaging.PathPositions.Device;
//入力されたフレームを取得する無名関数を使ったRGB32のみ受け入れるFrameQueueSink
_sink = new TIS.Imaging.FrameQueueSink( (img) => { return ShowImage( img ); }, new FrameType( MediaSubtypes.RGB32 ), 5 );
//sinkに受け渡す
icImagingControl1.Sink = _sink;
chkPPDevice.Checked = true;
chkPPSink.Checked = false;
chkPPDisplay.Checked = false;
btnBestFit.Checked = true;
}
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'画像ストリームにおけるOverlayBitmapオブジェクトの位置をコントロール
IcImagingControl1.OverlayBitmapPosition = TIS.Imaging.PathPositions.Device
'入力されたフレームを取得する無名関数を使ったRGB32のみ受け入れるFrameQueueSink
_sink = New FrameQueueSink(Function(img)
Return ShowImage(img)
End Function, New FrameType(MediaSubtypes.RGB32), 5)
IcImagingControl1.Sink = _sink
chkPPDevice.Checked = True
chkPPSink.Checked = False
chkPPDisplay.Checked = False
btnBestFit.Checked = True
End Sub
IC Imaging Controlではライブ表示、または保存したの画像上に描写することができます。 描画をする下準備としてライブ表示する前にoverlay bitmapオブジェクトのパスに Sinkを割り当てます。なお、OverlayBitmapの配置可能ポジションは下記の通りです。ライブ表示を開始する前にOverlayBitmapPositionを設定することで、どこのパスで使用するかを設定することができます。OverlayBitmapオブジェクトにアクセスするにはOverlayBitmapAtPathを使います。このプロパティのパラメータによってアクセスされるOverlayBitmapの位置を選択します。
名称 | 説明 |
---|---|
None | OverlayBitmapは表示されません。 |
Device | OverlayBitmapはライブ画像でもキャプチャ画像/動画でも表示されます。 |
Sink | OverlayBitmapはキャプチャ画像/動画では表示されますが、ライブ画像では表示されません。 |
Display | OverlayBitmapはライブ画像では表示されますが、キャプチャ画像/動画では表示されません。 |
オーバーレイオブジェクトを使用する
private void SetupOverlay( TIS.Imaging.OverlayBitmap ob )
{
// 描画用のオーバーレイするビットマップ画像を有効にする
ob.Enable = true;
// オーバーレイで表示する色をマゼンタ色にする
ob.DropOutColor = Color.Magenta;
// オーバーレイするビットマップ画像をドロップアウト カラーで塗りつぶす
ob.Fill( ob.DropOutColor );
// テキストの色は赤色で表示
ob.FontTransparent = true;
ob.DrawText( Color.Red, 10, 10, "IC Imaging Control 3.5" );
}
Private Sub SetupOverlay(ByVal ob As TIS.Imaging.OverlayBitmap)
' 描画用のオーバーレイするビットマップ画像を有効にする
ob.Enable = True
' オーバーレイで表示する色をマゼンタ色にする
ob.DropOutColor = Color.Magenta
' オーバーレイするビットマップ画像をドロップアウト カラーで塗りつぶす
ob.Fill(ob.DropOutColor)
Dim OldFont As Font = ob.Font
ob.Font = New Font("Arial", 10)
' テキストの色は赤色で表示
ob.FontTransparent = True
ob.DrawText(Color.Red, 10, 10, "IC Imaging Control 3.5")
ob.Font = OldFont
End Sub
上記のSetupOverlay関数ではオーバーレイを初期化(有効化、色指定、塗りつぶし)をします。 ライブ画像上に図やテキストを描画するためのオーバーレイデータ、メソッド、プロパティを制御するためにOverlayBitmapオブジェクトを使用します。
OverlayBitmapオブジェクトを有効にし、dropOutColorでマゼンタ色を設定しています。
overlay bitmap上に描写したフレームはビデオのの各フレームへコピーされますが、ドロップアウトカラーを指定することでライブ表示上に表示されないようにすることもできます。ここでは例のためにテキストやビットマップをオーバレイしていますがその他にも図形や塗りつぶしなどのメソッドも用意されています。
詳細は下記をご覧ください。
OverlayBitmap クラス
IC Imaging Control_Ver3.5(C#/VB.NET) APIリファレンスマニュアル
オーバーレイのセットアップ
LivePreparedのイベントハンドラーが発火したタイミング(ライブストリームの準備が完了した段階)でオーバーレイのセットアップをします。
PathPositionsがデバイス、シンク、ディスプレイパスのどの状態かによって描画する内容を変えています。
private void icImagingControl1_LivePrepared( object sender, EventArgs e )
{
if( icImagingControl1.DeviceValid )
{
if( (icImagingControl1.OverlayBitmapPosition & PathPositions.Device) != 0 )
{
SetupOverlay( icImagingControl1.OverlayBitmapAtPath[PathPositions.Device] );
// デバイス オーバーレイに座標を表示する
DrawCoordinatesystem( icImagingControl1.OverlayBitmapAtPath[PathPositions.Device] );
// オーバーレイ情報ボックスを描画
DrawOverlayInfo( icImagingControl1.OverlayBitmapAtPath[PathPositions.Device] );
}
if( (icImagingControl1.OverlayBitmapPosition & PathPositions.Sink) != 0 )
{
SetupOverlay( icImagingControl1.OverlayBitmapAtPath[PathPositions.Sink] );
// オーバーレイ情報ボックスを描画
DrawOverlayInfo( icImagingControl1.OverlayBitmapAtPath[PathPositions.Sink] );
}
if( (icImagingControl1.OverlayBitmapPosition & PathPositions.Display) != 0 )
{
SetupOverlay( icImagingControl1.OverlayBitmapAtPath[PathPositions.Display] );
// ビットマップ ファイルを読み込んで、ディスプレイ オーバーレイに表示する
ShowBitmap( icImagingControl1.OverlayBitmapAtPath[PathPositions.Display] );
// オーバーレイ情報ボックスを描画
DrawOverlayInfo( icImagingControl1.OverlayBitmapAtPath[PathPositions.Display] );
}
}
}
Private Sub IcImagingControl1_LivePrepared(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IcImagingControl1.LivePrepared
If IcImagingControl1.DeviceValid Then
SetupOverlay(IcImagingControl1.OverlayBitmapAtPath(PathPositions.Device))
SetupOverlay(IcImagingControl1.OverlayBitmapAtPath(PathPositions.Sink))
SetupOverlay(IcImagingControl1.OverlayBitmapAtPath(PathPositions.Display))
' Display a coordinate system on the device overlay
DrawCoordinatesystem(IcImagingControl1.OverlayBitmapAtPath(PathPositions.Device))
' Load a bitmap file and display it on the display overlay
If IcImagingControl1.OverlayBitmapPosition.Equals(PathPositions.Display) Then
ShowBitmap(IcImagingControl1.OverlayBitmapAtPath(PathPositions.Display))
End If
' Draw overlay info boxes
DrawOverlayInfo(IcImagingControl1.OverlayBitmapAtPath(PathPositions.Device))
DrawOverlayInfo(IcImagingControl1.OverlayBitmapAtPath(PathPositions.Sink))
DrawOverlayInfo(IcImagingControl1.OverlayBitmapAtPath(PathPositions.Display))
End If
End Sub
座標面を描く
ライブ表示画面に線トラベルでオーバーレイで座標面を描く関数です。
OverlayBitmap.DrawLineはライブ画面上に線を描画し、線を描き始めと描き終わりのピクセルのxy座標をしていることで任意の場所に線を描くことができます。
private void DrawCoordinatesystem( TIS.Imaging.OverlayBitmap ob )
{
// 画像の中心を計算
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;
}
Private Sub DrawCoordinatesystem(ByVal ob As TIS.Imaging.OverlayBitmap)
' 画像の中心を計算
Dim Col As Integer = _sink.OutputFrameType.Width / 2
Dim Row As Integer = _sink.OutputFrameType.Height / 2
Dim OldFont As Font = ob.Font
ob.Font = New Font("Arial", 8)
ob.DrawLine(Color.Red, Col, 0, Col, _sink.OutputFrameType.Height)
ob.DrawLine(Color.Red, 0, Row, _sink.OutputFrameType.Width, Row)
Dim i As Integer
For i = 0 To Row Step 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 Then
ob.DrawText(Color.Red, Col + 10, Row - i - 7, i / 10)
ob.DrawText(Color.Red, Col + 10, Row + i - 7, -i / 10)
End If
Next
For i = 0 To Col Step 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 Then
ob.DrawText(Color.Red, Col + i - 5, Row - 17, i / 10)
ob.DrawText(Color.Red, Col - i - 10, Row - 17, -i / 10)
End If
Next
ob.Font = OldFont
End Sub
オーバーレイのアップデート
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 );
//現在のフレーム番号を出力します。
//背景色を現在のドロップアウト色に設定し、フォントを不透明にする
ob.FontBackColor = ob.DropOutColor;
ob.FontTransparent = false;
//現在のフォントをセーブします。
Font OldFont = ob.Font;
// テキストを描画
ob.Font = new Font( "Arial", 8 );
ob.DrawText( Color.Yellow, 70, GetVideoDimension().Height - 19, frameCount.ToString() );
// 以前に使用したフォントを復元する
ob.Font = OldFont;
}
Private Sub IcImagingControl1_OverlayUpdate(ByVal sender As System.Object, ByVal e As TIS.Imaging.ICImagingControl.OverlayUpdateEventArgs) Handles IcImagingControl1.OverlayUpdate
Dim ob As TIS.Imaging.OverlayBitmap = e.overlay
Dim info = IcImagingControl1.DriverFrameDropInformation
Dim frameCount As Integer = info.FramesDelivered
Dim lineIndex As Integer = frameCount Mod 25
If lineIndex = 0 Then
' Delete the triangle.
ob.DrawSolidRect(ob.DropOutColor, 10, _
_sink.OutputFrameType.Height - 70, _
62, _
_sink.OutputFrameType.Height - 9)
End If
' Draw the new triangle line.
ob.DrawLine(Color.Yellow, lineIndex * 2 + 10, _
_sink.OutputFrameType.Height - 10, _
lineIndex * 2 + 10, _
_sink.OutputFrameType.Height - 10 - lineIndex)
' 現在のフレーム番号を出力します。
' 背景色を現在のドロップアウト色に設定し、フォントを不透明にする
ob.FontBackColor = ob.DropOutColor
ob.FontTransparent = False
' 現在のフォントをセーブします。
Dim OldFont As Font = ob.Font
' テキストを描画
ob.Font = New Font("Arial", 8)
ob.DrawText(Color.Yellow, 70, _sink.OutputFrameType.Height - 19, Str(frameCount) + " ")
' 以前に使用したフォントを復元する
ob.Font = OldFont
End Sub
このイベントは画像の取り込みより新しいフレームが転送された後に呼び出されますので、フレームごとに違う情報を挿入することができます。
フレームは変数FrameCountでカウントされ、 変数FrameCountは三角形のゲージを描くのに使用されます。もしカウンターが25を超えた場合、0にリセットされ三角形が消去されます。よって同じサイズで単一色の長方形をその三角形の上から描画する場合は、その長方形の色はDropOutColorとして設定し、透過させなければなりません。DrawSolidRectメソッドがこの機能を提供します。
時刻を表示
private void timer1_Tick( object sender, EventArgs e )
{
TIS.Imaging.OverlayBitmap ob = icImagingControl1.OverlayBitmapAtPath[TIS.Imaging.PathPositions.Device];
if( icImagingControl1.LiveVideoRunning )
{
// フォントを保存
Font OldFont = ob.Font;
ob.Font = new Font( "Arial", 14, FontStyle.Bold );
// ビデオ ウィンドウの左下隅に時間を描画
int Col = GetVideoDimension().Width - 81;
int Row = GetVideoDimension().Height - 20;
// 背景色と描画モードを設定
ob.FontTransparent = false;
ob.FontBackColor = Color.Black;
// 現在時刻を白色で描画。
ob.DrawText( Color.White, Col, Row, DateTime.Now.ToString( "T" ) );
// 前に使用したフォントを保存
ob.Font = OldFont;
}
}
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim ob = IcImagingControl1.OverlayBitmapAtPath(PathPositions.Device)
If IcImagingControl1.LiveVideoRunning Then
Dim OldFont As Font = ob.Font
ob.Font = New Font("Arial", 14, FontStyle.Bold)
' ビデオ ウィンドウの左下隅に時間を描画
Dim Col As Integer = _sink.OutputFrameType.Width - 81
Dim Row As Integer = _sink.OutputFrameType.Height - 20
' 背景色と描画モードを設定
ob.FontTransparent = False
ob.FontBackColor = Color.Black
' 現在時刻を白色で描画。
ob.DrawText(Color.White, Col, Row, DateTime.Now.ToString("T"))
' 前に使用したフォントを保存
ob.FontTransparent = True
ob.Font = OldFont
End If
End Sub
タイマーイベントで、ライブ画面に現在時刻を描画する関数です。
WindowsFormのタイマーを挿入し、タイマーイベントハンドラを使っています。
なお、FontBackColorがDropOutColorと同じ色の場合、テキストの背景にある長方形が表示されることはありません。
デフォルトのFontBackColorはblackです。
ビットマップ画像を描画
private void ShowBitmap( TIS.Imaging.OverlayBitmap ob )
{
try
{
// ここで簡単にアクセスできるように、hardware.bmp をプロジェクトのリソースとして追加
var bmp = Creating_an_Overlay.Properties.Resources.hardware;
// 列を計算して、Imaging Control の右上隅にビットマップを表示
int col = GetVideoDimension().Width - 5 - bmp.Width;
// OverlayBitmap の Graphics オブジェクトを取得
Graphics g = ob.GetGraphics();
// 描画
g.DrawImage( bmp, col, 5 );
// 描画が終了したらグラフィックスを解放
ob.ReleaseGraphics( g );
}
catch( Exception Ex )
{
MessageBox.Show( "File not found: " + Ex.Message );
}
}
Private Sub ShowBitmap(ByVal ob As TIS.Imaging.OverlayBitmap)
Try
' 簡単にアクセスできるように、hardware.bmp をプロジェクトのリソースとして追加
Dim TheBitmap As Image = Bitmap.FromFile(Application.StartupPath & "\..\..\hardware.bmp")
' 列を計算して、Imaging Control の右上隅にビットマップを表示
Dim Col As Integer = _sink.OutputFrameType.Width - 5 - TheBitmap.Width
'OverlayBitmap の Graphics オブジェクトを取得
Dim g As Graphics = ob.GetGraphics()
' 描画
g.DrawImage(TheBitmap, Col, 5)
' 描画が終了したらグラフィックスを解放
ob.ReleaseGraphics(g)
Catch Ex As System.Exception
MsgBox("File not found: " + Ex.Message, MsgBoxStyle.Information, "ShowBitmap")
End Try
End Sub
ShowBitmapはoverlay bitmapにビットマップ画像を描画するための関数です。
OverlayBitmap.GetGraphicsメソッドを使ってoverlay bitmapを描画するための.NET Graphicsオブジェクトを呼び出します。
オーバーレイのパスの位置を設定する
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();
}
Private Sub EnableOverlayBitmapAtPath(ByVal pos As TIS.Imaging.PathPositions, ByVal enabled As Boolean)
Dim wasLive As Boolean = IcImagingControl1.LiveVideoRunning
If wasLive Then IcImagingControl1.LiveStop()
Dim oldPos As TIS.Imaging.PathPositions = IcImagingControl1.OverlayBitmapPosition
If enabled Then
IcImagingControl1.OverlayBitmapPosition = oldPos Or pos
Else
IcImagingControl1.OverlayBitmapPosition = oldPos And Not pos
End If
If wasLive Then IcImagingControl1.LiveStart()
End Sub
指定されたパス位置のオーバーレイ ビットマップを有効または無効にします。
オーバーレイをグレースケールかカラーのどちらで表示するか
private void btnColor_CheckedChanged( object sender, EventArgs e )
{
//カラーのoverlay bitmap フォーマットです。
//オーバレイにカラーの線やテキストを描くことができます。
if ( btnColor.Checked )
SetOverlayBitmapColorModes( OverlayColorModes.Color );
}
private void btnGrayscale_CheckedChanged( object sender, EventArgs e )
{
//グレースケールのoverlay bitmap フォーマットです。
//線やテキストはグレースケールでしか描けません。
if ( btnGrayscale.Checked )
SetOverlayBitmapColorModes( OverlayColorModes.Grayscale );
}
private void btnBestFit_CheckedChanged( object sender, EventArgs e )
{
//overlay bitmapフォーマットは画像ストリームに合わせて最適なものが選択されます
if ( btnBestFit.Checked )
SetOverlayBitmapColorModes( OverlayColorModes.BestFit );
}
'カラーのoverlay bitmap フォーマット
Private Sub btnColor_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnColor.CheckedChanged
setOverlayBitmapColorModes(OverlayColorModes.Color)
End Sub
'グレースケールのoverlay bitmap フォーマット
Private Sub btnGrayscale_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGrayscale.CheckedChanged
setOverlayBitmapColorModes(OverlayColorModes.Grayscale)
End Sub
'overlay bitmapフォーマットは画像ストリームに合わせて最適なものが選択されます
Private Sub btnBestFit_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBestFit.CheckedChanged
setOverlayBitmapColorModes(OverlayColorModes.BestFit)
End Sub
OverlayBitmapのカラーモードを設定します。 これはオーバレイビットマップをカラーもしくはグレースケール画像どちらで表示するかを選択するものです。画像取り込みデバイスによって提供された画像はオーバレイの描画前の段階で選択された形式に変換されます。
オーバーレイをグレースケールかカラーのどちらで表示するかはオプションボタンで制御しています。ライブストリームがoverlay bitmap カラーモードに対応しない時には、その画像データは自動的に変換されます。
下記のAPIリファレンスマニュアルにもその他関数などの説明があります。
プログラマーズガイド:オーバーレイの作成
IC Imaging Control_Ver3.5(C#/VB.NET) APIリファレンスマニュアル