2010年6月11日金曜日

カメラのプレビューにOpenGLを重ねてみる

カメラのプレビューにOpenGLのモデルを重ねてみました。OpenGLのモデルは、ApiDemosのcom.example.android.apis.graphics.TranslucentGLSurfaceViewActivityで使われているCubeRendererを利用しました。
というか、むしろTranslucentGLSurfaceViewActivityにカメラのプレビューを突っ込んだ感じ。

まずは、layoutのXML。
<RelativeLayout
    android:id="@+id/RelativeLayout01"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    >
    <android.opengl.GLSurfaceView
        android:id="@+id/GlView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:keepScreenOn="true">
    </android.opengl.GLSurfaceView>
    <com.example.CameraView
        android:id="@+id/CameraPreview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
    </com.example.CameraView>
</RelativeLayout>
SurfaceViewを継承したCameraViewを追加しています。

次に、Activity。
package com.example;

import android.app.Activity;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
import android.os.Bundle;

public class GLTestActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 画面を構築
        setContentView(R.layout.main);

        // GL
        GLSurfaceView glSurfaceView = (GLSurfaceView)findViewById(R.id.GlView);
        glSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0); 
        glSurfaceView.setRenderer(new CubeRenderer(true));
        glSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
    }
}
ポイントはGLSerfaceView#setEGLConfigChooser()とSurfaceHolder#setFormat()です。
CubeRendererクラスは、ApiDemosそのままです。

最後に、CameraView.java
package com.example;

import android.content.Context;
import android.hardware.Camera;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder _holder;
    private Camera _camera;

    public CameraView(Context context) {
        super(context);

        // サーフェイスホルダーの生成
        _holder = getHolder();
        _holder.addCallback(this);
        
        // プッシュバッッファの指定
        _holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public CameraView(Context context, AttributeSet attrs) {
        super(context, attrs);

        // サーフェイスホルダーの生成
        _holder = getHolder();
        _holder.addCallback(this);
        
        // プッシュバッッファの指定
        _holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        // カメラのプレビュー開始
        Camera.Parameters parameters = _camera.getParameters();
        parameters.setPreviewSize(width, height);
        _camera.setParameters(parameters);
        _camera.startPreview();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // カメラの初期化
        try {
            _camera = Camera.open();
            _camera.setPreviewDisplay(holder);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // カメラのプレビュー停止
        _camera.setPreviewCallback(null);
        _camera.stopPreview();
        _camera.release();
        _camera = null;
    }
}

実現はできたのですが、いまいち良く分かっていません。これ以上進むには、OpenGLの勉強が必要ですね...

0 件のコメント:

コメントを投稿