72 votes

Comment dessiner une superposition sur une SurfaceView utilisé par la Caméra sur Android?

J'ai un programme simple qui attire l'aperçu de l' Camera en SurfaceView. Ce que j'essaie de faire est d'utiliser l' onPreviewFrame méthode, qui est appelée chaque fois qu'une nouvelle image est tirée dans l' SurfaceView, pour l'exécution de l' invalidate méthode qui est censé invoquer l' onDraw méthode. En fait, l' onDraw la méthode est appelée, mais rien n'est imprimé (je suppose que l'aperçu de la caméra est d'écraser le texte, je suis en train de dessiner).

C'est un de simplifier version de l' SurfaceView sous-classe que j'ai:

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);
 }
}

88voto

CommonsWare Points 402670

SurfaceView probablement ne fonctionne pas comme un simple View à cet égard.

Au lieu de cela, procédez de la manière suivante:

  1. Mettez votre SurfaceView à l'intérieur d'un FrameLayout ou RelativeLayoutdans votre mise en page fichier XML, comme les deux celles-ci permettent à l'empilement des widgets sur l'axe des Z
  2. Déplacez votre dessin logique dans une autre coutume View classe
  3. Ajouter une instance de la Vue personnalisée de classe à la disposition de fichier XML en tant que enfant de l' FrameLayoutou RelativeLayout, mais qu'elle s'affiche après l' SurfaceView

Ce sera la cause de votre coutume View classe semblent flotter au-dessus de l' SurfaceView.

Voir ici pour un exemple de projet que les couches de popup panneaux au-dessus d'un SurfaceView utilisé pour la lecture vidéo.

17voto

mahi Points 205

essayez d'appeler setWillNotDraw(faux) à partir de surfacecreated.. il a travaillé pour moi

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");
}

J'ai appelé invalider de onTouchEvent

public boolean onTouch(View v, MotionEvent event) {

    invalidate();
    return true;
}

1voto

Devashish Kunal Points 11

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X