VCDプロパティ:全プロパティ一覧を表示する編
概要
カメラデバイスの露光時間やゲイン等の機能を制御するためにVCDプロパティと呼ばれるIC Imaging Controlが用意したインターフェースがあります。VCDプロパティはツリー構造で構成されており、値、範囲、自動設定のような様々な含んでおり、このサンプルでは接続したそれらのVCDプロパティすべてをツリービュー形式で表示しています。
サンプルプログラム
Software | IC Imaging Control 3.5, Visual Studio™ 2019 |
---|---|
サンプル(C#) | list_vcdproperties_cs_3.5.zip |
サンプル(VB.NET) | list_vcdproperties_vb_3.5.zip |
実行結果
Visual Studioのプログラム上ではすでにボタンの設置や関数は定義済ですので、IC Imaging Contorl3.5をインストールされていれば、実行ボタンだけですぐにデバッグで動作確認することができます。
画面にあるそれぞれのボタンなどのコントローラの機能は下記の通りです。
[Select Device]ボタン | デバイスを選択するダイアログ画面を表示 |
---|---|
[Show Property Page]ボタン | デバイスプロパティのダイアログ画面を表示 |
Tree Viewer | カメラにある機能の一覧を表示し、選択した機能の設定を変更することができます。 |
初期設定
private void Form1_Load(object sender, EventArgs e)
{
if( !icImagingControl1.LoadShowSaveDeviceState("lastSelectedDeviceState.xml") )
{
MessageBox.Show("No device was selected.");
this.Close();
return;
}
// カメラの設定した解像度に合わせて表示画面を変更
icImagingControl1.LiveDisplayDefault = false;
icImagingControl1.LiveDisplaySize = icImagingControl1.Size;
//Tree Viewerの初期化
UpdateStateAfterDeviceSelect();
}
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If IcImagingControl1.DeviceValid = False Then
' SelectDeviceボタンイベントハンドラの呼び出し(デバイスセッティングダイアログを表示)
btnSelectDevice_Click(Me, Nothing)
End If
If IcImagingControl1.DeviceValid = True Then
' ライブストリーミング開始
IcImagingControl1.LiveStart()
' カメラの設定した解像度に合わせて表示画面を変更
IcImagingControl1.LiveDisplayDefault = False
IcImagingControl1.LiveDisplaySize = IcImagingControl1.Size
' Tree Viewerの初期化
QueryVCDProperties()
End If
End Sub
フォームロードするタイミングの処理内容です。
LoadShowSaveDeviceStateメソッドにてデバイスを割り当て、LiveDisplaySizeプロパティを使用することで、カメラの設定した解像度に合わせて表示画面を変更しています。
private void UpdateStateAfterDeviceSelect()
{
//すべてのプロパティ要素(PropertyElement)、およびインターフェイスを列挙
ListAllPropertyItems();
//ライブストリーミングを開始
icImagingControl1.LiveStart();
// TreeViewを初期化する
BuildVCDPropertiesTree();
}
初期設定で呼び出す内容として接続したカメラデバイスのプロパティおよびインターフェースを列挙したのちに、ライブストリーミングを開始しTreeViewにセットするところまで行っています。
下記ではListAllPropertyItemsとBuildVCDPropertiesTreeのぞれぞれの関数について説明します。
ListAllPropertyItems関数(すべてのプロパティ要素およびインターフェイスを列挙)
private void ListAllPropertyItems()
{
// すべてのプロパティ アイテムを取得する
foreach (TIS.Imaging.VCDPropertyItem PropertyItem in icImagingControl1.VCDPropertyItems)
{
System.Diagnostics.Debug.WriteLine(PropertyItem.Name);
// 現在のプロパティ アイテムのすべてのプロパティ要素を取得
foreach (TIS.Imaging.VCDPropertyElement PropertyElement in PropertyItem.Elements)
{
System.Diagnostics.Debug.WriteLine(" Element : " + PropertyElement.Name);
// 現在のプロパティ要素のすべてのインターフェイスを取得します。
foreach (TIS.Imaging.VCDPropertyInterface PropertyInterFace in PropertyElement)
{
System.Diagnostics.Debug.Write(" Interface ");
try
{
// 現在のインターフェイスを適切な型にキャストして、
// 特別なインターフェイス プロパティにアクセスします。
//AbsoluteValue:絶対値型
if ( PropertyInterFace.InterfaceGUID == TIS.Imaging.VCDGUIDs.VCDInterface_AbsoluteValue )
{
var AbsoluteValue = (TIS.Imaging.VCDAbsoluteValueProperty)PropertyInterFace;
System.Diagnostics.Debug.Write("Absolute Value : ");
System.Diagnostics.Debug.WriteLine(AbsoluteValue.Value.ToString());
}
//MapStrings:リスト型
else if ( PropertyInterFace.InterfaceGUID == TIS.Imaging.VCDGUIDs.VCDInterface_MapStrings )
{
var MapString = (TIS.Imaging.VCDMapStringsProperty)PropertyInterFace;
System.Diagnostics.Debug.Write("Mapstring : ");
System.Diagnostics.Debug.WriteLine(MapString.String);
}
//Switch:切り替え型
else if( PropertyInterFace.InterfaceGUID == TIS.Imaging.VCDGUIDs.VCDInterface_Switch )
{
var Switch = (TIS.Imaging.VCDSwitchProperty)PropertyInterFace;
System.Diagnostics.Debug.Write("Switch : ");
System.Diagnostics.Debug.WriteLine(Switch.Switch.ToString());
}
//Button:ボタン型
else if( PropertyInterFace.InterfaceGUID == TIS.Imaging.VCDGUIDs.VCDInterface_Button )
{
var Button = (TIS.Imaging.VCDButtonProperty)PropertyInterFace;
System.Diagnostics.Debug.WriteLine("Button");
}
//Range:閾値(範囲)型
else if( PropertyInterFace.InterfaceGUID == TIS.Imaging.VCDGUIDs.VCDInterface_Range )
{
var Range = (TIS.Imaging.VCDRangeProperty)PropertyInterFace;
System.Diagnostics.Debug.Write("Range : ");
System.Diagnostics.Debug.WriteLine(Range.Value.ToString());
}
}
catch( Exception ex )
{
System.Diagnostics.Debug.WriteLine("<error>:" + ex);
}
}
}
}
}
Private Sub ListAllPropertyItems()
Dim PropertyItem As TIS.Imaging.VCDPropertyItem
Dim PropertyElement As TIS.Imaging.VCDPropertyElement
Dim PropertyInterFace As TIS.Imaging.VCDPropertyInterface ' Default interface type.
'すべてのインターフェースを定義
Dim Range As TIS.Imaging.VCDRangeProperty
Dim Switch As TIS.Imaging.VCDSwitchProperty
Dim AbsoluteValue As TIS.Imaging.VCDAbsoluteValueProperty
Dim MapString As TIS.Imaging.VCDMapStringsProperty
Dim Button As TIS.Imaging.VCDButtonProperty
'aすべてのプロパティ アイテムを取得する
For Each PropertyItem In IcImagingControl1.VCDPropertyItems
System.Diagnostics.Debug.WriteLine(PropertyItem.Name)
' 現在のプロパティ アイテム(item)のすべてのプロパティ要素を取得
For Each PropertyElement In PropertyItem.Elements
System.Diagnostics.Debug.WriteLine(" Element : " + PropertyElement.Name)
' 現在のプロパティ要素(element)のすべてのインターフェイスを取得します。
For Each PropertyInterFace In PropertyElement
System.Diagnostics.Debug.Write(" Interface ")
Try
'現在のインターフェイスを適切な型にキャストして、
'特別なインターフェイス プロパティにアクセスします。
Select Case PropertyInterFace.InterfaceGUID
Case VCDGUIDs.VCDInterface_AbsoluteValue
AbsoluteValue = PropertyInterFace
System.Diagnostics.Debug.WriteLine("Absolut Value : " + AbsoluteValue.Value.ToString)
Case VCDGUIDs.VCDInterface_MapStrings
MapString = PropertyInterFace
System.Diagnostics.Debug.WriteLine("Mapstring : " + MapString.String)
Case VCDGUIDs.VCDInterface_Switch
Switch = PropertyInterFace
System.Diagnostics.Debug.WriteLine("Switch : " + Switch.Switch.ToString)
Case VCDGUIDs.VCDInterface_Button
Button = PropertyInterFace
System.Diagnostics.Debug.WriteLine("Button")
Case VCDGUIDs.VCDInterface_Range
Range = PropertyInterFace
System.Diagnostics.Debug.WriteLine("Range : " + Range.Value.ToString)
End Select
Catch ex As System.Exception
System.Diagnostics.Debug.WriteLine("<error>")
End Try
Next
Next
Next
End Sub
カメラにアクセスし、すべてのプロパティ要素(PropertyElement)、およびインターフェイスを列挙する方法を示しています。
VCDプロパティのすべてのプロパティにアクセスするためには、プロパティ項目、要素、インターフェースを指定する手段(VCDPropertyItems→PropertyElement→PropertyInterFace)でそれぞれのプロパティオブジェクトに順々にアクセスする必要があります。それぞれのクラスは下記の通りです。
VCDPropertyItem | カメラがサポートするVCDプロパティにアクセスするための機能(VCDPropertyItemオブジェクトのコレクションやVCDPropertyElementコレクション)を含むクラスです。 |
---|---|
VCDPropertyElement | エレメントを調整する為のインターフェースのセットを含んでおり、プロパティへの様々なアクセスメソッドが用意されています。 |
VCDPropertyInterFace | プロパティからデータを読み取り、またデータをプロパティに書き込むものです。下記のプロパティはこのVCDPropertyInterfaceを継承しております。 なお、現在のインターフェイスのプロパティに正しくアクセスするには、インターフェイスを範囲、絶対値などの適切なインターフェイス タイプに「キャスト」する必要があります。 |
BuildVCDPropertiesTreeItems関数(VCDPropertyItemをTreeViewに追加)
private void BuildVCDPropertiesTreeItems(TreeNode pp, TIS.Imaging.VCDPropertyItems props)
{
// すべての VCDPropertyItem を反復処理して、ツリーに挿入します
foreach (TIS.Imaging.VCDPropertyItem item in props)
{
// アイテムの新しいツリー ノードを作成します
TreeNode newNode = new TreeNode(item.Name, 0, 0);
pp.Nodes.Add(newNode);
//要素(element)を挿入
QueryVCDPropertyElements(newNode, item);
}
}
Private Sub QueryVCDPropertyItems(ByVal ParentNode As TreeNode, ByVal PropertyItems As TIS.Imaging.VCDPropertyItems)
' すべての VCDPropertyItem を反復処理して、ツリーに挿入します
For Each item As TIS.Imaging.VCDPropertyItem In PropertyItems
' アイテムの新しいツリー ノードを作成します
Dim newNode As New TreeNode(item.Name, 0, 0)
newNode.Tag = Nothing
ParentNode.Nodes.Add(newNode)
' 要素(element)を追加
QueryVCDPropertyElements(newNode, item)
Next
End Sub
カメラにあるアイテム(例えば、GainやExposureなど)をすべて、TreeViewに追加をしています。
QueryVCDPropertyElements関数(VCDPropertyElementをTreeViewのノードに追加)
private void QueryVCDPropertyElements(TreeNode pp, TIS.Imaging.VCDPropertyItem item)
{
foreach (TIS.Imaging.VCDPropertyElement elem in item.Elements)
{
TreeNode newNode = null;
//要素(element)の名前を割り振り
if( elem.ElementGUID == TIS.Imaging.VCDGUIDs.VCDElement_Value )
newNode = new TreeNode("VCDElement_Value: '" + elem.Name + "'", 1, 1);
else if ( elem.ElementGUID == TIS.Imaging.VCDGUIDs.VCDElement_Auto )
newNode = new TreeNode("VCDElement_Auto: '" + elem.Name + "'", 2, 2);
else if ( elem.ElementGUID == TIS.Imaging.VCDGUIDs.VCDElement_OnePush )
newNode = new TreeNode("VCDElement_OnePush: '" + elem.Name + "'", 3, 3);
else if ( elem.ElementGUID == TIS.Imaging.VCDGUIDs.VCDElement_WhiteBalanceRed )
newNode = new TreeNode("VCDElement_WhiteBalanceRed: '" + elem.Name + "'", 4, 4);
else if ( elem.ElementGUID == TIS.Imaging.VCDGUIDs.VCDElement_WhiteBalanceBlue )
newNode = new TreeNode("VCDElement_WhiteBalanceBlue: '" + elem.Name + "'", 4, 4);
else
newNode = new TreeNode("Other Element ID: '" + elem.Name + "'", 4, 4);
pp.Nodes.Add(newNode);
// インターフェースを挿入
QueryVCDPropertyInterface(newNode, elem);
}
}
Private Sub QueryVCDPropertyElements(ByVal ParentNode As TreeNode, ByVal PropertyItem As TIS.Imaging.VCDPropertyItem)
' generate a display name
Dim name As String
Dim Image As Integer
Dim Element As TIS.Imaging.VCDPropertyElement
For Each Element In PropertyItem.Elements
'要素(element)の名前を割り振り
Select Case Element.ElementGUID
Case VCDGUIDs.VCDElement_Value
name = "VCDElement_Value"
Image = 1
Case VCDGUIDs.VCDElement_Auto
name = "VCDElement_Auto"
Image = 2
Case VCDGUIDs.VCDElement_OnePush
name = "VCDElement_OnePush"
Image = 3
Case VCDGUIDs.VCDElement_WhiteBalanceRed
name = "VCDElement_WhiteBalanceRed"
Image = 4
Case VCDGUIDs.VCDElement_WhiteBalanceBlue
name = "VCDElement_WhiteBalanceBlue"
Image = 4
Case Else
name = "Other Element ID"
Image = 4
End Select
Dim newNode As New TreeNode(name + ": " + Element.Name, Image, Image)
newNode.Tag = Nothing
ParentNode.Nodes.Add(newNode)
' インターフェースを挿入
QueryVCDPropertyInterface(newNode, Element)
Next
End Sub
カメラの機能で同様な制御があるのかを判断し、それをVCDPropertyItemのノードの下に追加しています。
例えば、カメラの機能のゲインの場合値を設定するVCDElement_Valueや自動ゲイン機能を設定するVCDElement_Autoなどがあります。
これらの設定できるエレメントをその機能に応じて要素をノードに追加しています。
QueryVCDPropertyInterface関数(すべてのインターフェースを挿入)
private void QueryVCDPropertyInterface(TreeNode pp, TIS.Imaging.VCDPropertyElement elem)
{
foreach (TIS.Imaging.VCDPropertyInterface itf in elem)
{
TreeNode newNode;
if( itf.InterfaceGUID == TIS.Imaging.VCDGUIDs.VCDInterface_AbsoluteValue )
newNode = new TreeNode("AbsoluteValue", 4, 4);
else if( itf.InterfaceGUID == TIS.Imaging.VCDGUIDs.VCDInterface_MapStrings )
newNode = new TreeNode("MapStrings", 6, 6);
else if( itf.InterfaceGUID == TIS.Imaging.VCDGUIDs.VCDInterface_Range )
newNode = new TreeNode("Range", 4, 4);
else if( itf.InterfaceGUID == TIS.Imaging.VCDGUIDs.VCDInterface_Switch )
newNode = new TreeNode("Switch", 5, 5);
else if( itf.InterfaceGUID == TIS.Imaging.VCDGUIDs.VCDInterface_Button )
newNode = new TreeNode("Button", 3, 3);
else
{
newNode = new TreeNode(itf.InterfaceGUID.ToString(), 4, 4);
}
// Tag プロパティがノードでインターフェースを保持
newNode.Tag = itf;
pp.Nodes.Add(newNode);
}
}
Private Sub QueryVCDPropertyInterface(ByVal ParentNode As TreeNode, ByVal PropertyElement As TIS.Imaging.VCDPropertyElement)
Dim Name As String
Dim image As Integer
Dim Itf As TIS.Imaging.VCDPropertyInterface
'
For Each Itf In PropertyElement
'インターフェース(interface)の名前を割り振り
Select Case Itf.InterfaceGUID
Case VCDGUIDs.VCDInterface_AbsoluteValue
Name = "AbsoluteValue"
image = 4
Case VCDGUIDs.VCDInterface_MapStrings
Name = "MapStrings"
image = 6
Case VCDGUIDs.VCDInterface_Range
Name = "Range"
image = 4
Case VCDGUIDs.VCDInterface_Switch
Name = "Switch"
image = 5
Case VCDGUIDs.VCDInterface_Button
Name = "Button"
image = 3
Case Else
Name = "AbsoluteValue"
image = 4
End Select
'Tag プロパティがノードでインターフェースを保持
Dim newNode As New TreeNode(Name, image, image)
newNode.Tag = Itf.Parent.Parent.ItemGUID.ToString() + ":" + Itf.Parent.ElementGUID.ToString() + ":" + Itf.InterfaceGUID.ToString()
ParentNode.Nodes.Add(newNode)
Next
End Sub
VCDPropertyElementsのノードの下に使用できるすべてのインターフェースを追加していきます。
例えば、カメラのGainの機能ではAbsoluteValueやRangeが設定できるます。
それらの機能に応じて設定できる下記のインターフェースをノードに追加しています。
VCDAbsoluteValueProperty | 絶対値型 |
---|---|
VCDButtonProperty | ボタン型 |
VCDRangeProperty | 閾値(範囲)型 |
VCDMapStringsProperty | リスト型 |
VCDSwitchProperty | 切り替え型 |
これでカメラのすべてのプロパティへアクセスし、TreeViewへの表示・反映をすることができます。
VCDPropertyのコントロール
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
// Tagプロパティが空の場合
if (Tree.SelectedNode.Tag == null)
{
return;
}
// すべてのコントロールを隠す
foreach( var ctrl in _currentControls )
{
ctrl.Dispose();
}
_currentControls.Clear();
TIS.Imaging.VCDPropertyInterface itf = Tree.SelectedNode.Tag as TIS.Imaging.VCDPropertyInterface;
if (itf != null)
{
itf.Update();
// 選択したインターフェースのタイプに一致するコントロールグループを表示し、初期化します。
if ( itf.InterfaceGUID == TIS.Imaging.VCDGUIDs.VCDInterface_AbsoluteValue )
ShowAbsoluteValueControl(itf);
else if( itf.InterfaceGUID == TIS.Imaging.VCDGUIDs.VCDInterface_MapStrings)
ShowComboBoxControl(itf);
else if( itf.InterfaceGUID == TIS.Imaging.VCDGUIDs.VCDInterface_Range)
ShowRangeControl(itf);
else if( itf.InterfaceGUID == TIS.Imaging.VCDGUIDs.VCDInterface_Switch)
ShowSwitchControl(itf);
else if( itf.InterfaceGUID == TIS.Imaging.VCDGUIDs.VCDInterface_Button)
ShowButtonControl(itf);
}
}
Private Sub Tree_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles Tree.AfterSelect
' Tagプロパティが空の場合
If Tree.SelectedNode.Tag Is Nothing Then Exit Sub
If Not RangeCtrl Is Nothing Then RangeCtrl.Dispose()
If Not SwitchCtrl Is Nothing Then SwitchCtrl.Dispose()
If Not MapStringsCtrl Is Nothing Then MapStringsCtrl.Dispose()
If Not ButtonCtrl Is Nothing Then ButtonCtrl.Dispose()
If Not AbsValCtrl Is Nothing Then AbsValCtrl.Dispose()
Dim itfPath As String = Tree.SelectedNode.Tag
Dim itf As TIS.Imaging.VCDPropertyInterface = IcImagingControl1.VCDPropertyItems.FindInterface(itfPath)
If Not itf Is Nothing Then
itf.Update()
' 選択したインターフェースのタイプに一致するコントロールグループを表示し、初期化します。
Select Case itf.InterfaceGUID
Case VCDGUIDs.VCDInterface_AbsoluteValue
ShowAbsoluteValueControl(itf)
Case VCDGUIDs.VCDInterface_MapStrings
ShowComboBoxControl(itf)
Case VCDGUIDs.VCDInterface_Range
ShowRangeControl(itf)
Case VCDGUIDs.VCDInterface_Switch
ShowSwitchControl(itf)
Case VCDGUIDs.VCDInterface_Button
ShowButtonControl(itf)
End Select
End If
End Sub
TreeViewに表示されたプロパティを使って制御する方法について説明します。
上記で作成したインターフェースのノードのタグを使って、それぞれのインターフェースに対応したフォームを表示するようにします。
TreeViewに表示されたインターフェースノードをクリックすると、フォームに最適なコントロールが現れ、プロパティの設定を調整できます。正確なインターフェースを取得する為にFindInterfaceメソッドを使用し、FindInterfaceはインターフェースパス(もしくはGUID)をパラメータを特定しています。
private void ShowAbsoluteValueControl(TIS.Imaging.VCDPropertyInterface itf)
{
var newCtrl = new AbsValSlider((TIS.Imaging.VCDAbsoluteValueProperty)itf);
CtrlFrame.Controls.Add(newCtrl);
newCtrl.SetBounds(20, 20, 500, 27);
CtrlFrame.Text = "Absolute Value";
_currentControls.Add(newCtrl);
}
Private Sub ShowAbsoluteValueControl(ByVal itf As TIS.Imaging.VCDPropertyInterface)
AbsValCtrl = New AbsValSlider()
CtrlFrame.Controls.Add(AbsValCtrl)
AbsValCtrl.SetBounds(20, 20, 500, 27)
AbsValCtrl.AssignItf(itf)
CtrlFrame.Text = itf.Parent.Parent.Name + ": " + itf.Parent.Name ' Property item name
End Sub
プロパティ値の設定変更は上記のスライダーやチェックボックスやコンボボックスを実装したユーザーコントロールを使うことで調整することができます。
下記のAPIリファレンスマニュアルにもその他関数などの説明があります。
プログラマーズガイド:VCDプロパティをリストする
IC Imaging Control_Ver3.5(C#/VB.NET) APIリファレンスマニュアル