2010-05-29 19 views
61

que tienen un sencillo programa que señala a la vista previa de la Camera en un SurfaceView. Lo que estoy tratando de hacer es usar el método onPreviewFrame, que se invoca cada vez que una nueva trama se introduce en el SurfaceView, con el fin de ejecutar el método invalidate que se supone debe invocar el método onDraw. De hecho, se invoca el método onDraw, pero no se está imprimiendo nada (supongo que la vista previa de la cámara sobrescribe el texto que intento dibujar).¿Cómo dibujar una superposición en un SurfaceView utilizado por la cámara en Android?

Ésta es una versión de la SurfaceView simplificar subclase que tengo:

public class Superficie extends SurfaceView implements SurfaceHolder.Callback { 
SurfaceHolder mHolder; 
public Camera camera; 
Superficie(Context context) { 
    super(context); 
    mHolder = getHolder(); 
    mHolder.addCallback(this); 
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
} 
public void surfaceCreated(final SurfaceHolder holder) { 
    camera = Camera.open(); 
    try { 
    camera.setPreviewDisplay(holder); 
    camera.setPreviewCallback(new PreviewCallback() { 
    public void onPreviewFrame(byte[] data, Camera arg1) { 
    invalidar(); 
    } 
    }); 
    } catch (IOException e) {} 
} 
public void invalidar(){ 
    invalidate(); 
} 
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
    Camera.Parameters parameters = camera.getParameters(); 
    parameters.setPreviewSize(w, h); 
    camera.setParameters(parameters); 
    camera.startPreview(); 
} 
@Override 
public void draw(Canvas canvas) { 
    super.draw(canvas); 
    // nothing gets drawn :(
    Paint p = new Paint(Color.RED); 
    canvas.drawText("PREVIEW", canvas.getWidth()/2, 
    canvas.getHeight()/2, p); 
} 
} 
+0

puede u pls me ayude cómo u han hecho im tratando de cambiar el color de dibujo en el botón de clic como BUTTON1- > botón rojo2-> amarillo, etc. ¿cómo haré esto usando un lienzo? Quiero aplicar en la cámara en vivo igual que efectos de cámara en vivo trabajan – Erum

Respuesta

77

SurfaceView probablemente no funciona como un habitual View en este sentido.

En su lugar, haga lo siguiente:

  1. Deja tus SurfaceView en el interior de un FrameLayout o RelativeLayout en su archivo del formato XML, ya que ambos los permitir el apilamiento de los widgets en el eje Z
  2. Mueva su lógica de dibujo en un personalizado independiente View clase
  3. Añadir una instancia de la costumbre Ver clase para el archivo de diseño XML como un niño del FrameLayout o RelativeLayout, pero hacer que aparezca después de la SurfaceView

Esto hará que la clase personalizada View que aparezca flotar sobre el SurfaceView.

See here for a sample project que coloca paneles emergentes por encima de SurfaceView utilizados para la reproducción de video.

+0

Muchas gracias ... eso es un buen ejemplo y estoy seguro de que eso es todo lo que necesito para hacer lo que quiera :) – Cristian

+0

@CommonsWare Así será la respuesta que se suministra ¿Trabajas en una situación en la que intentas superponer una vista de superficie sobre otra vista de superficie? ¿Qué quieres decir con clase de vista personalizada? La razón por la que estoy pidiendo es porque estoy frente a un problema similar que se encuentra aquí: http://stackoverflow.com/questions/3548666/overlay-images-onto-camera-preview-surfaceview – GobiasKoffi

+0

@rohanbk: No se puede superponer dos Widgets 'SurfaceView', según lo entiendo. "¿Qué quieres decir con clase de vista personalizada?" - su propia subclase de 'android.view.View', o su propia subclase de una clase de widget existente. – CommonsWare

1

Creo que deberías llamar al método super.draw() primero antes de hacer nada en el sorteo del método SurfaceView.

+1

Eso es exactamente lo que hace en su original código :) – ITisha

16

intentar llamar a setWillNotDraw(false) de surfaceCreated:

public void surfaceCreated(SurfaceHolder holder) { 
    try { 
     setWillNotDraw(false); 
     mycam.setPreviewDisplay(holder); 
     mycam.startPreview(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     Log.d(TAG,"Surface not created"); 
    } 
} 

@Override 
protected void onDraw(Canvas canvas) { 

    canvas.drawRect(area, rectanglePaint); 
    Log.w(this.getClass().getName(), "On Draw Called"); 
} 

y llamando invalidate de onTouchEvent:

public boolean onTouch(View v, MotionEvent event) { 

    invalidate(); 
    return true; 
} 
Cuestiones relacionadas