VCDプロパティ
VCD プロパティは画像取り込みデバイスの設定を行うためのもので、包括的でハードウェアに依存せず、かつ拡張も可能です。
概要
DirectShow 画像取り込みデバイス用に2つのプロパティを定義しています。VideoProcAmpと CameraControlです。それらのプロパティ値を表すために唯一long型のデータが定義されています。このコンセプトにより非デバイス依存のコードを記述することが可能になりますが、問題が2つでてきます。
- いくつかの画像取り込みデバイスにはDirectShowが定義する以上のプロパティを備えているものがあります。
- 例えば"exposure (露光時間)"のようなプロパティの値を"long"で設定したとすると、その値に意味がなくなってしまいます。どの値が1/20.000 secに対応するのでしょう?DirectShowにはこの問題を克服するために負の値をつかうという方法があります。例えば -2という値は2のマイナス2乗を意味する為 1/4 秒となります。これらの負の値は 物理的に意味を持つ(このケースでは秒を表す) ことから"物理値"と呼ばれます。ただこの方法では正確性に問題がでてきます。物理値によって1/3 秒の露光時間を設定することは不可能です。同じような問題が "iris(絞り)" や "zoom(ズーム)"の設定時にもあてはまります。
新しい VCDプロパティは時間などの物理的な単位においてプロパティ値を調整できるインターフェースを提供し、そしてそのインターフェースは高い正確性を持っています。もし以前のバージョンのIC Imaging Control でも十分満足だというのであれば、VCDSimplePropertyクラスライブラリリファレンス>クラス>VCDSimplePropertyというヘルパークラスがあり、前に作成したコードもなんなく移植することが可能です。ただしこのクラスを使用する場合、新しいVCDプロパティの恩恵は受けることができません。
基本コンセプト
VCDプロパティはツリー構造で構成されています。さらにそれは値や自動設定というような要素を含んでいます。よってプロパティは名前と要素のセットを持ったオブジェクトということができるでしょう。このオブジェクトは VCDPropertyItemクラスライブラリリファレンス>クラス>VCDPropertyItemと呼ばれます。 要素は VCDPropertyElementクラスライブラリリファレンス>クラス>VCDPropertyElement と呼び、エレメントを調整する為のインターフェースのセットを含んでいます。そしてインターフェースはプロパティへの様々なアクセスメソッドを提供します。例えば VCDRangePropertyクラスライブラリリファレンス>クラス>VCDRangePropertyというインターフェースはDirectShowのプロパティアクセスと同様のものを提供します。 VCDAbsoluteValuePropertyクラスライブラリリファレンス>クラス>VCDAbsoluteValueProperty は物理的な単位を使って高精度なプロパティアクセスを提供します。 こういったことを考えると VCD プロパティの構成は明らかになります。プロパティ項目はプロパティ要素を含み、さらにそのなかに1つ以上のインターフェースがあるということになります。プロパティを操作する為には適切な項目、要素、インターフェースを呼び出す必要があるということです。スタートメニューから"VCD Property Inspector"を開き、VCD プロパティがどのように構成されているかをご覧になってください。
プロパティオブジェクトを見つける
プロパティオブジェクトを見つけるにはまず最初にプロパティ項目、要素、あるいはインターフェースを指定する手段が必要となります。VCDPropertyIDsクラスライブラリリファレンス>ヘルパークラス>VCDIDs モジュールにて定義されている全てのプロパティ項目、要素、インターフェースにはGUIDs (Global Unique Identifiers)という識別子が割り当てられており、それをVCDプロパティ内での検出に使用します。接続されているビデオキャプチャデバイスで支援されているプロパティ項目は全て VCDPropertyItemsクラスライブラリリファレンス>クラス>VCDPropertyItemsコレクションに含まれています。このコレクションはプロパティ項目、要素、インターフェースを呼び出すメソッドを提供します。 VCDPropertyItems.FindItemクラスライブラリリファレンス>クラス>VCDPropertyItems>VCDPropertyItems.FindItem Method、VCDPropertyItems.FindElementクラスライブラリリファレンス>クラス>VCDPropertyItems>VCDPropertyItems.FindElement Method、VCDPropertyItems.FindInterfaceクラスライブラリリファレンス>クラス>VCDPropertyItems>VCDPropertyItems.FindInterface Methodの3つのメソッドがそれにあたります。呼び出されるオブジェクトはFindItem用GUIDと他の二つ(FindElementとFindInterface)用のGUIDの組み合わせにより指定される必要があります。以下、それらをGUIDパスと呼ぶことにします。
インターフェースを見つける
前述の通り、インターフェースとはプロパティからデータを読み取り、またデータをプロパティに書き込むものでもあります。 必要なインターフェースを呼び出すためにはそのインターフェース用のGUIDパスをVCDPropertyItems.FindInterfaceクラスライブラリリファレンス>クラス>VCDPropertyItems>VCDPropertyItems.FindInterface Methodへのパラメータとして使用しますが、それを行う前にどのインターフェースを使用するかを決める必要があります。 自動 項目の場合( VCDPropertyElementクラスライブラリリファレンス>クラス>VCDPropertyElement, GUID: VCDElement_Auto) 、スイッチインターフェース ( VCDSwitchPropertyクラスライブラリリファレンス>クラス>VCDSwitchProperty, GUID: VCDInterface_Switch)を取得しようとします。値項目( 実際のプロパティ値)を使う場合は最適なインターフェースを探さなければなりません。 最適、あるいはもっとも高度なインターフェースは絶対値(absolute value) インターフェースとなります。 ( 詳細については VCDAbsoluteValuePropertyクラスライブラリリファレンス>クラス>VCDAbsoluteValueProperty をご参照ください)
最初に説明したように、絶対値インターフェースは高精度で、値がその通りの意味を持つことになります。次のコードは露光時間のプロパティ項目の要素値のための絶対値インターフェースを 取得しています。
' 絶対値インターフェースの宣言
Dim AbsValItf As ICImagingControl.VCDAbsoluteValueProperty
' 露光時間の絶対値インターフェースの取得
AbsValItf = ICImagingControl1.VCDPropertyItems.FindInterface( VCDHelpers.VCDIDs.VCDID_Exposure + ":" + _
VCDHelpers.VCDIDs.VCDElement_Value + ":" + _
VCDHelpers.VCDIDs.VCDInterface_AbsoluteValue )
If Not AbsValItf Is Nothing Then
' インターフェースの取得に成功...
Else
' 露光時間プロパティ項目の要素値の絶対値インターフェース ' はありません。
End If
// 絶対値インターフェースの宣言
private ICImagingControl.VCDAbsoluteValueProperty AbsValItf;
// 露光時間の絶対値インターフェースの取得
AbsValItf = (ICImagingControl.VCDAbsoluteValueProperty)IcImagingControl1.VCDPropertyItems.FindInterface(
VCDHelpers.VCDIDs.VCDID_Exposure + ":" +
VCDHelpers.VCDIDs.VCDElement_Value + ":" +
VCDHelpers.VCDIDs.VCDInterface_AbsoluteValue );
if ( AbsValItf != null )
{
// インターフェースの取得に成功 ...
}
else
{
// 露光時間プロパティ項目の要素値の絶対値インターフェース
// はありません。
}
絶対値インターフェースがこのプロパティに存在しない場合、マップストリング(map string)インターフェースを取得します。(VCDMapStringsProperty, GUID: VCDInterface_MapStrings). 絶対値インターフェースほどの正確性はありませんが、値に意味はあります。次のコードは露光時間のプロパティ項目の要素値のためのマップストリングインターフェースを取得しています。
' マップストリングインターフェースの宣言
Dim MapStringsItf As ICImagingControl.VCDMapStringsProperty
' 露光時間のマップストリングインターフェースの呼び出し
MapStringsItf =
ICImagingControl1.VCDPropertyItems.FindInterface( VCDHelpers.VCDIDs.VCDID_Exposure + ":" + _
VCDHelpers.VCDIDs.VCDElement_Value + ":" + _
VCDHelpers.VCDIDs.VCDInterface_MapStrings )
If Not MapStringsItf Is Nothing Then
' インターフェースの呼び出しに成功 ...
Else
' 露光時間プロパティ項目の要素値のマップストリングインターフェース
' はありません。
End If
// マップストリングインターフェースの宣言
private ICImagingControl.VCDMapStringsProperty MapStringsItf;
// 露光時間のマップストリングインターフェースの呼び出し
MapStringsItf =
(ICImagingControl.VCDAbsoluteValueProperty)IcImagingControl1.VCDPropertyItems.FindInterface(
VCDHelpers.VCDIDs.VCDID_Exposure + ":" +
VCDHelpers.VCDIDs.VCDElement_Value + ":" +
VCDHelpers.VCDIDs.VCDInterface_MapStrings );
if ( MapStringsItf != null )
{
// インターフェースの呼び出しに成功 ...
}
else
{
// 露光時間プロパティ項目の要素値のマップストリングインターフェース
// はありません。
}
マップストリングインターフェースがこのプロパティに存在しない場合、レンジ(range)インターフェースを呼び出します。( VCDRangePropertyクラスライブラリリファレンス>クラス>VCDRangeProperty, GUID: VCDInterface_Range). このインターフェースは値に意味を持たせるものではありませんが、マップストリングよりも多くの値を提供することも可能です。 次のコードは露光時間のプロパティ項目の要素値のためのレンジインターフェースを呼び出しています。
' レンジインターフェースの宣言
Dim RangeItf As ICImagingControl.VCDRangeProperty
' 露光時間のレンジインターフェースの呼び出し
RangeItf = ICImagingControl1.VCDPropertyItems.FindInterface( VCDHelpers.VCDIDs.VCDID_Exposure + ":" + _
VCDHelpers.VCDIDs.VCDElement_Value + ":" + _
VCDHelpers.VCDIDs.VCDInterface_Range )
If Not RangeItf Is Nothing Then
' インターフェースの呼び出しに成功 ...
Else
' 露光時間プロパティ項目の要素値のレンジインターフェース
' はありません。
End If
// レンジインターフェースの宣言
private ICImagingControl.VCDRangeProperty RangeItf;
//' 露光時間のレンジインターフェースの呼び出し
RangeItf = (ICImagingControl.VCDAbsoluteValueProperty)IcImagingControl1.VCDPropertyItems.FindInterface(
VCDHelpers.VCDIDs.VCDID_Exposure + ":" +
VCDHelpers.VCDIDs.VCDElement_Value + ":" +
VCDHelpers.VCDIDs.VCDInterface_Range );
if ( RangeItf != null )
{
// インターフェースの呼び出しに成功 ...
}
else
{
// 露光時間プロパティ項目の要素値のレンジインターフェース
// はありません。
}
インターフェースを使う
前のセクションではインターフェースの取得について説明しました。ここではそれを使ってプロパティの情報を取得し、値を設定する方法について説明します。全てのインターフェースが以下のプロパティを提供します。
- Available:インターフェースが利用可能であるかを示します。例えば、トリガープロパティ項目のインターフェースはライブ画像を流している間は利用できない可能性があります。
- ReadOnly:インターフェースの値を設定できるかどうかを示します
- Default:デフォルトの値
- Value:インターフェースの値
絶対値インターフェースとレンジインターフェースは実際値に設定できる最小と最大の値についての情報を得るためのプロパティを提供します。絶対値インターフェースは追加として値の物理単位の情報を提供し、 マップストリングインターフェースは文字列コレクションを提供し、これが実際値に設定できる可能性のある値の集まりを構成します。
絶対値インターフェースが呼び出せる場合、インターフェースにアクセスするためのコードは次のようになります。
' AbsValItf は露光時間の有効な絶対値インターフェースです
If AbsValItf.Available Then
' 現在の値を平均値とする
AbsValItf.Value = ( AbsValItf.RangeMin + AbsValItf.RangeMax ) / 2
End If
// AbsValItf は露光時間の有効な絶対値インターフェースです
if ( AbsValItf.Available )
{
// 現在の値を平均値とする
AbsValItf.Value = ( AbsValItf.RangeMin + AbsValItf.RangeMax ) / 2;
}
マップストリングインターフェースが呼び出せる場合、インターフェースにアクセスするためのコードは次のようになります。
' MapStringsItf は露光時間の有効なマップストリングインターフェースです
If MapStringsItf.Available Then
' 現在の値を平均値とする
MapStringsItf.Value = ( MapStringsItf.RangeMin + MapStringsItf.RangeMax ) / 2
End If
// MapStringsItf は露光時間の有効なマップストリングインターフェースです
if ( MapStringsItf.Available )
{
// 現在の値を平均値とする
MapStringsItf.Value = ( MapStringsItf.RangeMin + MapStringsItf.RangeMax ) / 2;
}
インターフェースが呼び出せる場合、インターフェースにアクセスするためのコードは次のようになります。
' RangeItf は露光時間の有効なレンジインターフェースです
If RangeItf.Available Then
' 現在の値を平均値とする
RangeItf.Value = ( RangeItf.RangeMin + RangeItf.RangeMax ) / 2
End If
// RangeItf は露光時間の有効なレンジインターフェースです
if ( RangeItf.Available )
{
// 現在の値を平均値とする
RangeItf.Value = ( RangeItf.RangeMin + RangeItf.RangeMax ) / 2;
}
プロパティ値のシリアライズ
VCDPropertyItemsクラスライブラリリファレンス>クラス>VCDPropertyItems は VCDPropertyItems.Saveクラスライブラリリファレンス>クラス>VCDPropertyItems>VCDPropertyItems.Save Method というメソッドを提供し、それによって接続されているデバイスの全VCDプロパティ設定を文字列にシリアライズします。プロパティ値はXMLフォーマットで保存されます。よって後に復元する時のためにその文字列をレジストリやファイルに保存したりというのが簡単にできます。XMLへの対応は公式に明記されておらず 予告なく変更される場合があります。全てのプロパティ値を保存するのには VCDPropertyItems.Loadクラスライブラリリファレンス>クラス>VCDPropertyItems>VCDPropertyItems.Load Methodが呼び出されます。