コーデックのプロパティを保存する

コーデックの利用とそのプロパティの保存、ロードについて説明します。
今回のサンプルプログラムのVB.NET 、C#用のソースコードはMy Documents/IC Imaging Control 3.4内の以下ののディレクトリに格納されています。
samples\VB *\Saving Codec Properties
samples\C# *\Saving Codec Properties

概要

コーデックとはビデオストリームを圧縮、そして伸長するものです。コンプレッサーまたはAVIコンプレッサーを意味する場合もあります。

いくつかのコーデックのプロパティはIC Imaging Controlで呼び出し、割り当てることができます。例えばビデオストリームの質を保存する前に設定することもできます。
コーデックプロパティはバイナリデータストリームとして供給されます。アプリケーションがデータをロードする際に はデータストリームの長さに応じて必要となるメモリー領域の大きさが変わるため、それを事前に知っておくことが重要になります。
データストリームがバイナリデータであるので、ファイル保存形式もバイナリデータである必要があります。
コーデックからのバイナリデータストリームを変更しないようにしてください。データがコーデックに対応しなくなり、予期せぬエラーを起こす可能性があります。また、あるコーデックのコーデックプロパティ同士 がお互いに対応しない場合もあります。 IC Imaging Control はエラーメッセージを表示することでこれらの問題を引き起こさないようにします。

コーデックはAviCompressorクラスライブラリリファレンス>クラス>AviCompressor オブジェクトが扱う外部DLLファイルであり、AviCompressorクラスライブラリリファレンス>クラス>AviCompressor オブジェクトが無効になると、その DLLはメモリーから消去されてしまいます。この場合、ほとんどのコーデックは設定されたプロパティを失ってしまいます。したがってこのような問題を避けるために、グローバルオブジェクトAviCompressorクラスライブラリリファレンス>クラス>AviCompressor をフォーム内で宣言することが推奨されます。
PropertyPageAvailableクラスライブラリリファレンス>クラス>AviCompressor>AviCompressor.PropertyPageAvailable PropertyTrueのコーデックでデータの呼び出し、割り当てが行えるため、プログラム実行前にこのプロパティをチェックしておくことが必要です。

プロジェクトの新規作成

新しいプロジェクトを作成し、IC imaging Controlをフォームに追加してください。 フォームに3つのボタンを追加し、 CaptionプロパティをそれぞれSave DataLoad DataShow Property Pageとします。またcmdSaveDatacmdLoadDatacmdShowPropertyPageと名前を付けます。 最低一つコンボボックスをフォームに追加してcboVideoCodecと名前を付けます。 

ここにコーデック名が入ります。

コーデックを作成する

まずはじめに、アプリケーションはコーデックデータを含むグローバルオブジェクト AviCompressorクラスライブラリリファレンス>クラス>AviCompressor が必要です。 AviCompressorクラスライブラリリファレンス>クラス>AviCompressor のプロパティはメモリーより消去された場合に全て消えてしまうため、グローバルオブジェジェクトである必要があります。よって次の一行をフォームの初めの部分に記述してください。

[VB.NET]
Dim Codec As TIS.Imaging.AviCompressor
[C#]
private TIS.Imaging.AviCompressor Codec;

フォームに Form_Load イベントプロシージャを追加して、コンボボックスにコーデック名が入るよう次のコードを入力します。

[VB.NET]
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) 
         Handles MyBase.Load
    'cboVideoCodec コンボボックスにインストール済みのコーデックを挿入する。 
    For Each Codec As TIS.Imaging.AviCompressor In IcImagingControl1.AviCompressors         cboVideoCodec.Items.Add(Codec)
    Next
    ' コンボボックス内の最初のコーデックを表示する
    cboVideoCodec.SelectedIndex = 0  

    Codec = CType(cboVideoCodec.SelectedItem(), TIS.Imaging.AviCompressor)

    ' ボタンを有効化、または無効化する。
    cmdShowPropertyPage.Enabled = Codec.PropertyPageAvailable
    cmdLoadData.Enabled = Codec.PropertyPageAvailable
    cmdSaveData.Enabled = Codec.PropertyPageAvailable
End Sub
[C#]
private void Form1_Load(object sender, EventArgs e)
{
    // cboVideoCodec コンボボックスにインストール済みのコーデックを挿入する。
    foreach (TIS.Imaging.AviCompressor _Codec in icImagingControl1.AviCompressors)
    {
         cboVideoCodec.Items.Add(_Codec);
     }
     // コンボボックス内の最初のコーデックを表示する
     cboVideoCodec.SelectedIndex = 0;

     Codec = (TIS.Imaging.AviCompressor)cboVideoCodec.SelectedItem;

    // ボタンを有効化、または無効化する。
    cmdShowPropertyPage.Enabled = Codec.PropertyPageAvailable;
    cmdLoadData.Enabled = Codec.PropertyPageAvailable;
    cmdSaveData.Enabled = Codec.PropertyPageAvailable;
}

このコードはAviCompressorsクラスライブラリリファレンス>クラス>AviCompressor>ICImagingControl.AviCompressors Property プロパティを使って利用可能なコーデックのリストを作成します。見てわかるように、グローバル変数 Codec がFor Each .. In .. ステートメントでアイテムとして使われています。 最初の利用可能コーデックはグローバルオブジェクトAviCompressorクラスライブラリリファレンス>クラス>AviCompressor Codecに割り当てられます。3つのボタンはAviCompressorクラスライブラリリファレンス>クラス>AviCompressorオブジェクト内でプロパティPropertyPageAvailableクラスライブラリリファレンス>クラス>AviCompressor>AviCompressor.PropertyPageAvailable Propertyに従って有効化、無効化されます。これによってコーデックが支援していない動作を回避することができます。
コンボボックスcboVideoCodecのSelectedValueChangedイベントプロシージャをフォームに追加してください。

[VB.NET]
Private Sub cboVideoCodec_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) 
Handles cboVideoCodec.SelectedIndexChanged
    Codec = CType(cboVideoCodec.SelectedItem(), TIS.Imaging.AviCompressor)

    ' ボタンの有効化もしくは無効化
    cmdShowPropertyPage.Enabled = Codec.PropertyPageAvailable
    cmdLoadData.Enabled = Codec.PropertyPageAvailable
    cmdSaveData.Enabled = Codec.PropertyPageAvailable
End Sub
[C#]
private void cboVideoCodec_SelectedIndexChanged(object sender, EventArgs e)
{
    Codec = (TIS.Imaging.AviCompressor)cboVideoCodec.SelectedItem;
    // ボタンの有効化もしくは無効化
    cmdShowPropertyPage.Enabled = Codec.PropertyPageAvailable;
    cmdLoadData.Enabled = Codec.PropertyPageAvailable;
    cmdSaveData.Enabled = Codec.PropertyPageAvailable;
}

コンボボックスで選択されたアイテムは AviCompressorクラスライブラリリファレンス>クラス>AviCompressor オブジェクトを参照します。このアイテムはグローバルオブジェクト AviCompressorクラスライブラリリファレンス>クラス>AviCompressor Codecに割り当てられます。
AviCompressorクラスライブラリリファレンス>クラス>AviCompressor のプロパティ PropertyPageAvailableクラスライブラリリファレンス>クラス>AviCompressor>AviCompressor.PropertyPageAvailable Property はボタンの有効化、無効化に使われます。これによってユーザーがコーデックのプロパティダイアログがないにも関わらずcmdShowPropertyPageボタンを押すというようなことを防ぎます。
では次にcmdShowPropertyPageボタンのクリックイベントプロシージャをフォームに追加してください。

[VB.NET]
Private Sub cmdShowPropertyPage_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) 
Handles cmdShowPropertyPage.Click
    Codec.ShowPropertyPage()
End Sub
[C#]
private void cmdShowPropertyPage_Click(object sender, EventArgs e)
{
     Codec.ShowPropertyPage();
}

コーデックプロパティを保存する

前述のように、コーデックプロパティはバイナリデータストリームとして供給されます。バイナリデータストリームとは単にバイトが並んでいるものです。ファイルの初期要素としてデータストリームのバイトカウントを保存することが強く推奨されます。データがファイルにロードされる際にこの初期要素を使うことで動的配列はバイトカウントに応じてサイズを変更し、データを格納できるようにします。
cmdSaveDataのクリックイベントプロシージャをフォームに追加します。

[VB.NET]
Private Sub cmdSaveData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) 
             Handles cmdSaveData.Click
    Try
        Dim Filestream As New System.IO.FileStream
                 ("test.bin", System.IO.FileMode.Create, System.IO.FileAccess.Write)
        ' データ用のライターを作成
        Dim BinWriter As New System.IO.BinaryWriter(Filestream)

        BinWriter.Write(Codec.ToString())
        BinWriter.Write(Codec.CompressorDataSize)
        BinWriter.Write(Codec.CompressorData)

        BinWriter.Close()
        Filestream.Close()
    Catch ex As System.Exception
         MsgBox(ex.Message, MsgBoxStyle.Critical, "Write error")
    End Try
End Sub
[C#]
private void cmdLoadData_Click(object sender, EventArgs e)
{
     try
     {
        System.IO.FileStream Filestream = new System.IO.FileStream
                        ("test.bin", System.IO.FileMode.Open, System.IO.FileAccess.Read);
        System.IO.BinaryReader BinReader = new System.IO.BinaryReader(Filestream);
        BinWriter.Write(Codec.Name);
        BinWriter.Write(Codec.CompressorDataSize);
        BinWriter.Write(Codec.CompressorData);

        BinWriter.Close();
        Filestream.Close();
    }
    catch (Exception Ex)
    {
        MessageBox.Show(Ex.Message);
    }
}

コーデックプロパティがtest.binに保存されます。AviCompressor.PropertyPageAvailableTrueである場合はcmdSaveDataボタンだけが有効であることに注意してください。また、代替案として、次のコードを実装することもできます。

[VB.NET]
If Codec.PropertyPageAvailable Then
    ' 何か実行する(保存など)
Else
    MsgBox "This codec does not support properties!"
End If
[C#]
if ( Codec.PropertyPageAvailable )
{
    //  何か実行する(保存など)
}
else
{
    MessageBox.Show( "This codec does not support properties!");
}

コーデックプロパティをロードする

cmdLoadDataのクリックイベントプロシージャをフォームに追加します。

[VB.NET]
Private Sub cmdLoadData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
                                 Handles cmdLoadData.Click
    Try
        ' データのリーダーを作成
        Dim Filestrem As New System.IO.FileStream("test.bin", System.IO.FileMode.Open, System.IO.FileAccess.Read) 
        Dim BinReader As New System.IO.BinaryReader(Filestrem)

        Dim CodecName As String

         ' コーデックコンフィギュレーションファイルよりコーデック名を呼び出し
        CodecName = BinReader.ReadString()

         ' 現在のコーデック名とファイルの中のコーデック名を比較
        If Codec.Name = CodecName Then
            Dim codecDataLen As Integer = BinReader.ReadInt32()
            ' コーデックにコンフィギュレーションデータを割り当てる
            Codec.CompressorData = BinReader.ReadBytes(codecDataLen)
        Else
            MsgBox ("The saved data does not match to the used codec." + Chr(13) + _
                   "saved: " + CodecName + Chr(13) + _
                   "used: " + Codec.Name)
        End If
        BinReader.Close()
        Filestrem.Close()
    Catch ex As System.Exception
        MsgBox (ex.Message, MsgBoxStyle.Critical, "Read error")
    End Try
End Sub
[C#]
private void cmdLoadData_Click(object sender, EventArgs e)
{
    try
    {
        System.IO.FileStream Filestream =
      new System.IO.FileStream("test.bin", System.IO.FileMode.Open, System.IO.FileAccess.Read);
        System.IO.BinaryReader BinReader = new System.IO.BinaryReader(Filestream);
        String CodecName;

          // コーデックコンフィギュレーションファイルよりコーデック名を呼び出し
          CodecName = BinReader.ReadString();

          //現在のコーデック名とファイルの中のコーデック名を比較
        if (Codec.Name == CodecName)
        {
            // バイナリデータの長さを読み取る
            int codecDataLen = BinReader.ReadInt32();
            // コーデックにコンフィギュレーションデータを割り当てる
            Codec.CompressorData = BinReader.ReadBytes(codecDataLen);
        }
        else
        {
            MessageBox.Show("The saved data does not match to the used codec.\n" +
                    "saved: " + CodecName + "\n" +
                    "used: " + Codec.Name);
        }
        BinReader.Close();
        Filestream.Close();
    }
    catch (Exception Ex)
    {
        MessageBox.Show(Ex.Message);
    }
}

cmdSaveDataボタンの部分で述べたように、
cmdLoadDataボタンはAviCompressor.PropertyPageAvailableクラスライブラリリファレンス>クラス>AviCompressor>AviCompressor.PropertyPageAvailable PropertyTrueである場合のみ有効です。コーデックにデータを割り当てる前に、プロパティを支援しているかどうかをチェックしてください。

[VB.NET]
If Codec.PropertyPageAvailable Then
     ' 何か実行する(ロードなど)
Else
     MsgBox "This codec does not support properties!"
End If
[C#]
if ( Codec.PropertyPageAvailable )
{
    //  何か実行する(ロードなど)
}
else
{
     MessageBox.Show( "This codec does not support properties!");
}

キャプチャ用にコーデックを使用する

完全にするために、以下の文を追加してAVIファイルをキャプチャするためにコーデックをどのように使用するかを示します。

[VB.NET]
IcImagingControl1.AviStartCapture("test.avi", Codec)
[C#]
icImagingControl1.AviStartCapture("test.avi",Codec);

このコードはサンプルプログラムには含まれていません。