公開日:2009/11/1 0:00:00

NyARToolKit for Java

Section 10 ソースコード解説 JMF周り

JMF Capture処理の埋め込み

ウェブカメラから映像を取り込む部分になります。

これまでと同様の方法でクラスを作成します。
具体的には、Packageは jp.sixwish.NyARToolKit.Sample、NameはCapture
Superclassは空欄のまま、Interfacesをjp.nyatla.nyartoolkit.jmf.utils.JmfCaptureListenerを指定。
チェックボックスは三箇所「Constructors from superclass」 「Inherited abstract methods」「Generate comments」とします。

/**
 * 
 */
package jp.sixwish.NyARToolKit.Sample.util;

import javax.media.Buffer;

import jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureListener;

/**
 * @author F.Rokubou
 *
 */
public class Capture implements JmfCaptureListener {

    /* (non-Javadoc)
     * @see jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureListener#onUpdateBuffer(javax.media.Buffer)
     */
    @Override
    public void onUpdateBuffer(Buffer i_buffer) {
        // TODO Auto-generated method stub

    }

}

まずは、キャプチャデバイス…ウェブカメラから取得した画像を表示する機能を実装するために、 コードを追加します。

/**
 * Sixwish.jp 実験用サンプルパッケージ
 * 
 * @copyright (C) 2009 The Sixwish project
 * @license http://sixwish.jp/licenses/nyartkgpl The GPL License
 */
package jp.sixwish.NyARToolKit.Sample.util;

/**
 * @see javax.media.Buffer
 * @see javax.swing.JFrame
 * @see javax.swing.JOptionPane
 */
import javax.media.Buffer;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

/**
 * @see jp.nyatla.nyartoolkit.NyARException
 * @see jp.nyatla.nyartoolkit.core.param.NyARParam
 * @see jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureDevice
 * @see jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureDeviceList
 * @see jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureListener
 */
import jp.nyatla.nyartoolkit.NyARException;
import jp.nyatla.nyartoolkit.core.param.NyARParam;
import jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureDevice;
import jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureDeviceList;
import jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureListener;

/**
 * Webカメラからの映像を取得するイベントリスナー
 * 
 * @author F.Rokubou
 */
public class Capture implements JmfCaptureListener {
    /**
     * ウィンドウのサイズ
     */
    private static final int SCREEN_X = 640;
    private static final int SCREEN_Y = 480;
    
    /**
     * @see jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureDevice
     */
    private JmfCaptureDevice _captureDev = null;
    
    /**
     * @see jp.nyatla.nyartoolkit.core.param.NyARParam
     */
    private NyARParam _nyARParam = null;
    
    /**
     * @see jp.nyatla.nyartoolkit.jogl.utils.GLNyARRaster_RGB
     */
    private GLNyARRaster_RGB _nyARRaster = null;

    /**
     * Constructor
     */
    public Capture() {
        this._init();
    }
    
    /**
     * 初期化処理
     */
    private void _init() {
        //キャプチャの準備
        try {
            /*
             * 複数のキャプチャデバイスがあって切り替えとかやる場合はこの辺りを工夫するべし
             */
            JmfCaptureDeviceList devlist = new JmfCaptureDeviceList();
            _captureDev = devlist.getDevice(0);
            _captureDev.setCaptureFormat(SCREEN_X, SCREEN_Y, 20f);

            // NyARToolkitの準備
            _nyARParam = new NyARParam();
            _nyARParam.changeScreenSize(SCREEN_X, SCREEN_Y);
            
            // GL対応のRGBラスタオブジェクト
            _nyARRaster = new GLNyARRaster_RGB(_nyARParam, _captureDev.getCaptureFormat());
            
            _captureDev.setOnCapture(this);
            _captureDev.start();
        } catch (NyARException e) {
            // カメラデバイスが認識できない時に例外が出るので、その対策
            // メッセージは、大半の例外がカメラデバイスが認識できない例外なのでこうしているだけ。
            e.printStackTrace();
            JOptionPane.showMessageDialog(new JFrame().getContentPane(),"キャプチャデバイスの接続状態を確認してください","キャプチャデバイスエラー",JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        }
    }
    
    /**
     * @see jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureListener#onUpdateBuffer(javax.media.Buffer)
     */
    @Override
    public void onUpdateBuffer(Buffer i_buffer) {
        try {
            synchronized (_nyARRaster) {
                _nyARRaster.setBuffer(i_buffer);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 
     * @return JmfCaptureDevice
     */
    public JmfCaptureDevice getCaptureDevice() {
        return _captureDev;
    }
    
    /**
     * 
     * @return NyARParam
     */
    public NyARParam getARParam() {
        return _nyARParam;
    }

    /**
     * 
     * @return GLNyARRaster_RGB
     */
    public GLNyARRaster_RGB getARRaster() {
        return _nyARRaster;
    }
}

Captureクラスができたので、これをパネル側から使うようにコードを書き換えます。
MainPanel.javaに対していくつか編集を行います

まず、クラスをインポートします。 動画は画像の連続ということで、Animatorクラスがキャプチャした画像を連続で再表示してくれるような機能を持っているので、それを使用。 さらに先ほど作ったクラスを使用します。

/**
 * @see com.sun.opengl.util.Animator
 */
import com.sun.opengl.util.Animator;

/**
 * @see jp.sixwish.NyARToolKit.Sample.util.Capture
 */
import jp.sixwish.NyARToolKit.Sample.util.Capture;

クラス変数に、インポートしたクラスを定義。

    /**
     * Eclipse Warning 対策
     */
    private static final long serialVersionUID = 1L;
    
    /**
     * @see jp.sixwish.NyARToolKit.Sample.util.Capture
     */
    Capture capture = null;
    
    /**
     * @see com.sun.opengl.util.Animator
     */
    Animator animator = null;

初期化処理の中に、それらのクラスを使うようにと処理を追加します。

    /**
     * 初期化処理
     * ここに各種リスナーを登録する処理を埋め込む。
     */
    protected void _init() {
        capture = new Capture();
        
        // 再描画用に Animatorスレッド を生成してスタートさせる
        animator = new Animator(this);
        animator.start();
    }

実行しても何も映らないので、次の実装を行いますが、長いので次へ。