メモリバッファコレクションを使用する

ここではメモリバッファコレクションの作成の仕方について説明します。これはユーザー割り当てるバッファを使用するものです。

このサンプルは IC Imaging Controlインストールディレクトリの %TOPLEVEL%\samples\VCx\MemBufferCollectionにあります。たとえばVC++2010 では %TOPLEVEL%\Samples\VC10となり、VC8 では%TOPLEVEL%\Samples\VC8です。プログラムを実行するため、ディレクトリ内のソリューションファイルMemBufferCollection.slnを開き メニューからビルド -> ビルド MemBufferCollectionと選択します。そこからデバッグ -> スタートと選択することでプログラムを実行することができます。

デバイスをオープンにする

この例では%TOPLEVEL%\Samples\VC71\Common\CmdHelper.hにあるsetupDeviceFromFile関数を使用します。この関数はデバイス選択ダイアログを表示し、そこで選択されたデバイスをコンフィギュレーションファイルに保存します。その情報は再度関数がコールされた際にロードされます。

Grabber grabber;
if( !setupDeviceFromFile( grabber ) )
{
  return -1;
}

必要なバッファサイズを特定する

必要なユーザー割り当てバッファのサイズを特定するために、最適なカラーフォーマットでFrameHandlerSinkクラスライブラリリファレンス>クラス>FrameHandlerSinkを設定し(この場合はeY800 )、Grabber::prepareLiveクラスライブラリリファレンス>クラス>Grabber>Grabber::prepareLive Methodをコールしています。この後、FrameHandlerSink::getOutputFrameTypeクラスライブラリリファレンス>クラス>FrameHandlerSink>FrameHandlerSink::getOutputFrameType Methodを呼び出すことでsink formatを取得することができます。

// イメージバッファのフォーマットをeY800に設定。 eY800はモノクロ、各ピクセル8bit(1 byte)のフォーマット。
// 1つのバッファでシンクにMemBufferCollectionを作成させる
tFrameHandlerSinkPtr pSink = FrameHandlerSink::create( eY800, 1 );

// snap modeを使用
pSink->setSnapMode( true );

// sinkの設定
grabber.setSinkType( pSink );

// sinkの出力サイズを取得するためにライブ画像の準備
if( !grabber.prepareLive( false ) )
{
  std::cerr << "Could not render the VideoFormat into a eY800 sink.";
  return -1;
}

// 出力タイプとハンドラシンクのサイズを取得
// フィルタを使用している場合、シンクのサイズはVideoFormatによって変わります。
FrameTypeInfo info;
pSink->getOutputFrameType( info );

ユーザー割り当てバッファでMemBufferCollectionを作成する

シンクのフォーマットを取得したので適切なサイズのバッファを作成することができるようになりました。
FrameTypeInfo::buffersizeクラスライブラリリファレンス>クラス>FrameTypeInfo>FrameTypeInfo::buffersize Propertyは1つのイメージのバイト数を保持しています。
MemBufferCollectionクラスライブラリリファレンス>クラス>MemBufferCollectionMemBufferCollection::createクラスライブラリリファレンス>クラス>MemBufferCollection>MemBufferCollection::create Methodをコールすることで作成され、フレームタイプ、バッファ数、バッファ配列をパラメータとします。

BYTE* pBuf[5];
// 上記で算出したサイズのイメージバッファを5つ割り当てる
for( int i = 0; i < 5; ++i )
{
  pBuf[i] = new BYTE[info.buffersize];
}

// 自分のイメージバッファを使用する新しいMemBufferコレクションの作成
tMemBufferCollectionPtr pCollection = MemBufferCollection::create( info, 5, pBuf );
if( pCollection == 0 || !pSink->setMemBufferCollection( pCollection ) )
{
  std::cerr << "Could not set the new MemBufferCollection, because types do not match.";
  return -1;
}

画像のキャプチャと保存

MemBufferCollectionが立ち上がると、プログラムが5枚のフレームをバッファ内にキャプチャし、ディスクに保存します。

// ライブモード開始。startLive()にはfalseが
// 渡されているためライブ画像はディスプレイ表示されません。
grabber.startLive( false );

// 5フレームをキャプチャし、上で作成したMemBufferCollectionにコピー
pSink->snapImages( 5 );

// ライブモードの停止
grabber.stopLive();

// デバイスをクローズする
grabber.closeDev();

// MemBufferコレクション内にある5つのフレームを別々のファイルにコピー
pCollection->save( "file*.bmp" );