2010-05-29 11 views
61

J'ai un programme simple qui dessine l'aperçu du Camera dans un SurfaceView. Ce que j'essaie de faire est d'utiliser la méthode onPreviewFrame, qui est invoquée chaque fois qu'une nouvelle image est dessinée dans le SurfaceView, afin d'exécuter la méthode invalidate qui est censée invoquer la méthode onDraw. En fait, la méthode onDraw est invoquée, mais rien n'est imprimé (je suppose que l'aperçu de la caméra écrase le texte que j'essaie de dessiner).Comment dessiner une superposition sur un SurfaceView utilisé par Camera sur Android?

Ceci est une version simplify de la sous-classe SurfaceView je:

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

u peut me aider pls comment u ont fait im essayant de changer de couleur de dessin sur le bouton cliquez comme BUTTON1- > button2-> jaune etc comment vais-je faire cela en utilisant la toile? Je veux appliquer sur caméra en direct même que les effets de caméra en direct travail – Erum

Répondre

77

SurfaceView ne fonctionnera probablement pas comme un View régulièrement à cet égard.

Au lieu de cela, procédez comme suit:

  1. Mettez votre SurfaceView à l'intérieur d'un FrameLayout ou RelativeLayout dans votre fichier XML de mise en page, puisque les deux ceux qui permettent l'empilement des widgets sur l'axe Z
  2. Déplacez votre logique de dessin dans une autre personnalisée View classe
  3. Ajouter une instance de la vue personnalisée classe dans le fichier XML de mise en page comme un enfant du FrameLayout ou RelativeLayout, mais ont apparaître après la SurfaceView

Cela entraînera votre classe personnalisée View à semblent flotter au-dessus du SurfaceView.

See here for a sample project couches superposant les panneaux au-dessus d'un SurfaceView utilisé pour la lecture vidéo.

+0

Merci beaucoup ... c'est un bel exemple et je suis sûr que c'est tout ce que j'ai besoin de faire ce que je veux :) – Cristian

+0

@CommonsWare Donc, cette réponse que vous avez fourni travailler dans une situation où vous essayez de superposer une vue de surface sur une autre surface? Que voulez-vous dire par classe personnalisée View? La raison pour laquelle je demande est parce que je suis confronté à un problème similaire situé ici: http://stackoverflow.com/questions/3548666/overlay-images-onto-camera-preview-surfaceview – GobiasKoffi

+0

@rohanbk: Vous ne pouvez pas superposer deux Les widgets 'SurfaceView', si je comprends bien. "Qu'entendez-vous par classe de vue personnalisée?" - votre propre sous-classe de 'android.view.View', ou votre propre sous-classe d'une classe de widget existante. – CommonsWare

1

Je pense que vous devriez appeler la méthode super.draw() avant de faire quoi que ce soit dans la méthode draw de surfaceView.

+1

C'est exactement ce qu'il fait dans son original code :) – ITisha

16

Essayez d'appeler 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"); 
} 

et appeler invalidate de onTouchEvent:

public boolean onTouch(View v, MotionEvent event) { 

    invalidate(); 
    return true; 
}