1

Android カメラを使用するアプリがあります。

CameraManagerカメラ、開閉、カメラパラメータ、フレームバッファに関係するすべてを処理するクラスのようなものを実装したいと考えています。

問題は、GUIから分離したいということですが、Android では、プレビューを取得CameraManagerするために が必要なため、カメラは GUI から分離できないようです。surfaceView

私が持っていた 1 つのアイデアは、初期化後に GUI マネージャーにCameraManager戻り、その後のすべてを GUI マネージャーに処理させることです。しかし、Camera Manager はまだ GUI に触れているため、十分に分離されていません。surfaceViewCameraManager

このカプセル化を最大化する方法について何か考えはありますか?

4

2 に答える 2

1

提案された Google メソッドを使用して、XML でビューを実装してみませんか。2 つのカスタム surfaceview を作成します (私の場合、1 つは GLSurfaceView で、もう 1 つは SurfaceView でした)。1 つのビューはカメラを実装し、2 つ目のビューはグラフィックやボタンを使用して GUI を処理できます。重要なのは、拡張された SurfaceView と GLSurfaceView のクラス名を使用するカスタム GLSurfaceView と SurfaceView を XML で作成することです。また、GUI ビューを透明にする必要があります。グラフィックは、ここには含まれていない MainRenderer クラスで描画されることに注意してください。以下のコードには OpenGL コンテキストの損失に関する問題があることに注意してください。この問題は現在修正中です。以下に示すコードは、作業を進めるのに十分なはずですが、mod なしでは単独では機能しません... 以下のコードのほとんどは、Google の OpenGl チュートリアルから派生したものです。

OpenGl ES 1.0 チュートリアル

すべてを分離するための独自のモッズを使用します。

XML は次のとおりです。

  <?xml version="1.0" encoding="utf-8"?>
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >                         
<com.zypath.opengltest.MainSurfaceView
    android:id="@+id/glSurfaceView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />                                       
<com.zypath.opengltest.CameraView
    android:id="@+id/camera"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:keepScreenOn="true" />
<LinearLayout
    android:id="@+id/status"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <TextView
         android:id="@+id/mangle"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:text="@string/mangle"
         android:textColor="@color/mcolor" />                       
</LinearLayout>   

メインコードの一部:

  public class Main extends Activity {
  ...


   @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // When working with the camera, it's useful to stick to one orientation.
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

    //Set full screen
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    setContentView(R.layout.main);

    //Substantiate surfaces
    cameraView = (CameraView) findViewById(R.id.camera);
    mGLView = (MainSurfaceView) findViewById(R.id.glSurfaceView);        

    //Initialize TextViews
    txtView = (TextView) findViewById(R.id.mangle);
    txtView.setText("Angle: " + String.valueOf(mAngle)); 


}

カスタム MainSurfaceView の一部

  public class MainSurfaceView extends GLSurfaceView {
...

//Constructor
public MainSurfaceView(Context context, AttributeSet attrs) {       
    super(context, attrs);
    this.context = context;

    mRenderer = new MainRenderer();
    setEGLConfigChooser(8, 8, 8, 8, 16, 0); 

    setRenderer(mRenderer);
    getHolder().setFormat(PixelFormat.TRANSLUCENT);    

    setZOrderOnTop(true);

    //Render only when there is a change
    setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);         
}

//TouchEvent handler
  @Override
public boolean onTouchEvent(MotionEvent event) {

    x = event.getX();
    y = event.getY();

    .....

    return true;
}

カメラコードの一部:

  public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
  ...
private Camera camera;
SurfaceHolder holder;

public CameraView(Context context, AttributeSet attrs) {
    super(context, attrs);
    // We're implementing the Callback interface and want to get notified
    // about certain surface events.
    getHolder().addCallback( this );
    // We're changing the surface to a PUSH surface, meaning we're receiving
    // all buffer data from another component - the camera, in this case.
    getHolder().setType( SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS );
}

public void surfaceCreated( SurfaceHolder holder ) {
    // Once the surface is created, simply open a handle to the camera hardware.
    camera = Camera.open();
}

public void surfaceChanged( SurfaceHolder holder, int format, int width, int height ) {

        camera.setPreviewDisplay( holder );

    camera.startPreview();
}
于 2012-06-20T23:53:35.123 に答える
0

サーフェス ビューをパラメーターとして CameraManager コンストラクターに渡します。マネージャーをオープンソースにしてくれることを願っています:)

編集:これは私が古いプロジェクトで使用したものです(共有は良いことです:P)

カメラビュー

パッケージ at.fhb.triangulate.gui;
android.content.Context をインポートします。
android.content.res.Resources.Theme をインポートします。
android.view.View をインポートします。
at.fhb.triangulate.main.TriangulateMain をインポートします。


/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Apache ライセンス、バージョン 2.0 (「ライセンス」) に基づいてライセンス供与されています。
 * ライセンスに準拠する場合を除き、このファイルを使用することはできません。
 * ライセンスのコピーは、次の URL で入手できます。
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * 適用法で義務付けられている場合、または書面で合意されている場合を除き、ソフトウェア
 * ライセンスに基づいて配布されるものは、「現状のまま」で配布されます。
 * 明示または黙示を問わず、いかなる種類の保証または条件もありません。
 *許可を管理する特定の言語については、ライセンスを参照してください。
 * ライセンスに基づく制限。
 */

android.app.Activity をインポートします。
android.content.Context をインポートします。
android.graphics.Canvas をインポートします。
android.hardware.Camera をインポートします。
android.hardware.Camera.Size をインポートします。
android.os.Bundle をインポートします。
android.view.SurfaceHolder をインポートします。
android.view.SurfaceView をインポートします。
android.view.Window をインポートします。

import java.io.IOException;
java.util.List をインポートします。


public class CameraView extends SurfaceView implement SurfaceHolder.Callback {
    SurfaceHolder mHolder;
    カメラ mCamera;

    public CameraView(Context context) {
        スーパー(コンテキスト);

        // SurfaceHolder.Callback をインストールして、
        // 下にあるサーフェスが作成され、破棄されます。
        mHolder = getHolder();
        mHolder.addCallback(これ);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder ホルダー) {
        // サーフェスが作成されました。カメラを取得し、場所を伝えます
        // 描く。
        mCamera = Camera.open();
        試す {
           mCamera.setPreviewDisplay(ホルダー);
        } キャッチ (IOException 例外) {
            mCamera.release();
            mCamera = null;
            // TODO: ここに例外処理ロジックを追加します
        }
    }

    public void surfaceDestroyed(SurfaceHolder ホルダー) {
        // 戻ると Surface が破壊されるので、プレビューを停止します。
        // CameraDevice オブジェクトは共有リソースではないため、
        // アクティビティが一時停止したときに解放することが重要です。
        mCamera.stopPreview();
        mCamera = null;
    }


    public void surfaceChanged(SurfaceHolder ホルダー、int 形式、int w、int h) {
        // これでサイズがわかったので、カメラ パラメータを設定して開始します
        // プレビュー。
        Camera.Parameters パラメータ = mCamera.getParameters();
        parameters.setPreviewSize(w, h);
       // parameters.set("orientation", "portrait");

        mCamera.setParameters(パラメータ);
        mCamera.startPreview();
    }

}



于 2012-04-22T18:15:13.860 に答える