jueves, 26 de abril de 2012

Realidad Aumentada en Android. Acceso a la cámara.

Realidad Aumentada es la habilidad de superponer puntos de información sobre la vista ofrecida por la cámara del dispositivo móvil. La Realidad Aumentada permite aumentar la información ofrecida por la cámara del dispositivo móvil, e interacturar con sensores y dispositivos como el magnetómetro, acelerómetro o geolocalización y ofrecer esta información añadida junto con la imagen ofrecida por la cámara. A la hora de desarrollar alguna aplicación de realidad aumentada, la base es acceder a los dispositivos y sensores del teléfono móvil; cámara, mágnetometro y acelerómetro y GPS.


Acceso a la vista de la cámara


El primer paso para implementar un entorno de realidad aumentada es acceder a la cámara para tener una vista del entorno real en el que se ofrece la funcionalidad deseada. Se debe dar permiso a la aplicación para acceder a la cámara del dispositivo, para lo que se modifica el Manifest de la aplicación


<application android:icon="@drawable/icon" 
                android:label="@string/app_name"
                android:debuggable="true">
...
<uses-permission android:name="android.permission.CAMERA" />
...
</application>



Lo siguiente es tener acceso a la vista de superficie de la camara sobre la que se va a pintar las imágenes capturadas. por la cámara. Para esto se extiende la clase SurfaceView. Se debe acceder a la clase SurfaceHolder para acceder y controlar la superficie subyacente, asi mismo, se debe implementar la clase interna Callback de la clase SurfaceHolder para recibir información acerca de cambios en la superficie. La superficie manejada es solo accesible entre llamadas a los métodos surfaceCreated y surfaceDestroyed. La implementación de la clase Callback se añade a la clase SurfaceHolder mediante el método addCallback.
En el método surfaceCreated recupero una instancia a la cámara mediante Camera.open y posteriormente se añade el acceso a la superficie subyacente mediante el método setPreviewDisplay. En el método surfaceChanged se actualizan los parámetros de la cámara y se inicia la previsualización de la imagen en la cámara. El método surfaceDestroyed cierra la cámara y libera recursos de la cámara.


package com.m607.camera;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.view.SurfaceHolder;

public class CameraCallback implements SurfaceHolder.Callback{
    Camera camera;
 Context ctx;
 SurfaceHolder surfaceHolder;

 public CameraCallback(Context ctx, SurfaceHolder surfaceHolder){
  this.ctx = ctx;
  this.surfaceHolder= surfaceHolder;
 }

 public void surfaceCreated(SurfaceHolder holder) {
  camera = Camera.open();
  try {
   camera.setPreviewDisplay(surfaceHolder);
  } catch (Throwable t) {
  }
 }

 public void surfaceChanged(SurfaceHolder holder, int format,
   int width, int height) {
  Parameters parameters = camera.getParameters();
  parameters.setPreviewSize(width, height);
  parameters .setPictureFormat(PixelFormat.JPEG);
  
  if (ctx.getResources().getConfiguration().orientation !=
   Configuration.ORIENTATION_LANDSCAPE) {
   // This is an undocumented although widely known feature
   parameters.set("orientation", "portrait");
   // For Android 2.2 and above
   //camera.setDisplayOrientation(90);
   // Uncomment for Android 2.0 and above
   //parameters.setRotation(90);
   } else {
   // This is an undocumented although widely known feature
   parameters.set("orientation", "landscape");
   // For Android 2.2 and above
   //camera.setDisplayOrientation(0);
   // Uncomment for Android 2.0 and above
   //parameters.setRotation(0);
   }
  

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

 public void surfaceDestroyed(SurfaceHolder arg0) {
  stopCamera();
 }
 public void stopCamera(){
  camera.stopPreview();
  camera.release();
  camera = null;
 }

}








package com.m607.camera;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class CameraView extends SurfaceView {

 SurfaceHolder surfaceHolder;

 CameraCallback surfaceHolderCallback;

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

  surfaceHolder = this.getHolder();
  surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
 
  surfaceHolderCallback = new CameraCallback(ctx, surfaceHolder);
  surfaceHolder.addCallback(surfaceHolderCallback);

 }
 
 public void stopCamera(){
  surfaceHolderCallback.stopCamera();
 }
 
}


Solo falta acceder a la manejador de la cámara desde la actividad principal



 private CameraView cameraView;
        /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    try{
       super.onCreate(savedInstanceState);
       cameraView = new CameraView(
          this.getApplicationContext());
                 this.setContentView(cameraView);
    } catch(Exception e){}
    }

2 comentarios:

  1. Hola Oscar, interesante la explicación.

    ResponderEliminar
  2. Oscar, tendras información sobre como pintar los puntos de interes("Realidad Aumentada") usando el gps.

    ResponderEliminar