Как разделить камеру и графический интерфейс в Android?

1

У меня есть приложение, которое использует камеру Android.

Я хочу реализовать что-то вроде класса CameraManager, которое будет касаться всего, что связано с камерой, открытия, закрытия, параметров камеры и буфера кадров.

Дело в том, что я хочу отделить CameraManager от графического интерфейса, но в Android камера кажется неотделимой от графического интерфейса, потому что для получения предварительного просмотра вам необходим surfaceView просмотр.

Одна из CameraManager surfaceView в том, что CameraManager возвратит surfaceView в GUI-менеджер, после инициализации CameraManager, и после этого менеджер GUI обрабатывает все. Но он недостаточно отделился, потому что диспетчер камеры по-прежнему трогает GUI.

Любые мысли о том, как я могу максимизировать эту инкапсуляцию?

Теги:
camera
user-interface
encapsulation

2 ответа

1

Почему бы не использовать предложенный метод Google и реализовать представления в XML. Создайте два пользовательских вида поверхности (в моем случае один был GLSurfaceView, а другой - SurfaceView). Один вид реализует камеру, а второй может обрабатывать графический интерфейс с графикой и/или кнопками. Ключ создает пользовательский GLSurfaceView и SurfaceView в XML, который использует имена классов расширенных SurfaceView и GLSurfaceView. Также вы должны сделать прозрачный вид графического интерфейса. Обратите внимание, что графика рисуется в классе MainRenderer, который здесь не включен. Помните, что приведенный ниже код имеет проблемы с потерей контекста OpenGL, которые я исправляю. Код, показанный ниже, должен быть достаточным, чтобы помочь вам начать работу, но он не будет работать на нем без модов... Большая часть приведенного ниже кода получена из Googles OpenGl Tutorial

Учебник 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 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();
}
0

передать представление поверхности в качестве параметра в конструктор CameraManager. Надеюсь, вы создадите менеджера с открытым исходным кодом :)

edit: это то, что я использовал в старом проекте (совместное использование - это хорошо: P)

CameraView

package at.fhb.triangulate.gui;
import android.content.Context;
import android.content.res.Resources.Theme;
import android.view.View;
import at.fhb.triangulate.main.TriangulateMain;


/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;

import java.io.IOException;
import java.util.List;


public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
    SurfaceHolder mHolder;
    Camera mCamera;

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

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, acquire the camera and tell it where
        // to draw.
        mCamera = Camera.open();
        try {
           mCamera.setPreviewDisplay(holder);
        } catch (IOException exception) {
            mCamera.release();
            mCamera = null;
            // TODO: add more exception handling logic here
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // Surface will be destroyed when we return, so stop the preview.
        // Because the CameraDevice object is not a shared resource, it very
        // important to release it when the activity is paused.
        mCamera.stopPreview();
        mCamera = null;
    }


    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // Now that the size is known, set up the camera parameters and begin
        // the preview.
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPreviewSize(w, h);
       // parameters.set("orientation", "portrait");

        mCamera.setParameters(parameters);
        mCamera.startPreview();
    }

}



  • 0
    Ваше решение не является идеальным либо .. потому что диспетчер камеры все равно должен будет реализовывать SurfaceHolder.Callback .. или если я заставлю графический интерфейс реализовывать его, то мне придется заставить графический интерфейс касаться камеры. какого черта они спроектировали это так ?! Кстати, это не будет с открытым исходным кодом, к сожалению: P
  • 0
    Я не уверен на 100%, если это возможно (какое-то время я что-то делал с камерой), вы не можете передать обратный вызов в качестве параметра? или создайте новый интерфейс обратного вызова. Этот новый обратный вызов может быть реализован из графического интерфейса, вызванного из исходного обратного вызова, который затрагивает весь код камеры?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню