2010-05-29 15 views
61

Mam prosty program, który rysuje podgląd Camera w SurfaceView. Próbuję użyć metody onPreviewFrame, która jest wywoływana za każdym razem, gdy nowa klatka jest wciągana do SurfaceView, aby wykonać metodę invalidate, która ma wywoływać metodę onDraw. W rzeczywistości wywoływana jest metoda onDraw, ale nic tam nie jest drukowane (domyślam się, że podgląd kamery zastępuje tekst, który próbuję narysować).Jak narysować nakładkę na SurfaceView używanym przez aparat na Androida?

Jest to uproszczenie wersja SurfaceView podklasy mam:

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

może u pls mi pomóc jak u zrobili im próbuje zmienić kolor kliknij przycisk rysunek jak BUTTON1- > czerwony przycisk2-> żółty itp. Jak to zrobić, używając płótna? Chcę aplikować na żywo z kamery tak samo jak efekty z kamery na żywo – Erum

Odpowiedz

77

SurfaceView prawdopodobnie nie działa jak zwykły View w tym względzie.

Zamiast tego, należy wykonać następujące czynności:

  1. Połóż SurfaceView wewnątrz FrameLayout lub RelativeLayout w pliku XML szablonu, ponieważ oba te umożliwiają układanie widżety na oś Z
  2. Przenieś logikę rysowania do osobnego klienta klasa
  3. Dodaj wystąpienie niestandardowego widoku klasa do pliku XML jako układ dziecka z FrameLayout lub RelativeLayout, ale mają pojawić po SurfaceView

To spowoduje, że klasa zwyczaj View pojawiać się unosić nad SurfaceView.

See here for a sample project to panele z wyskakującymi warstwami powyżej SurfaceView używane do odtwarzania wideo.

+0

Dziękuję bardzo ... to miły przykład i jestem pewien, że to wszystko, co muszę zrobić, co chcę :) – Cristian

+0

@CommonsWare Więc ta odpowiedź, którą dostarczyłeś pracować w sytuacji, w której próbujesz nałożyć jeden widok powierzchni na inny widok powierzchni? Co masz na myśli przez niestandardową klasę Wyświetl? Powodem, dla którego pytam, jest to, że mam do czynienia z podobnym problemem znajdującym się tutaj: http://stackoverflow.com/questions/3548666/overlay-images-onto-camera-preview-surfaceview – GobiasKoffi

+0

@rohanbk: Nie można nałożyć dwóch Widgety 'SurfaceView', jak rozumiem. "Co masz na myśli przez niestandardową klasę Wyświetl?" - twoja własna podklasa 'android.view.View' lub twoja własna podklasa istniejącej klasy widżetów. – CommonsWare

1

Myślę, że powinieneś najpierw wywołać metodę super.draw() zanim zrobisz cokolwiek w metodzie rysowania surfaceView.

+1

To jest dokładnie to, co robi w swoim oryginale kod :) – ITisha

16

Spróbuj zadzwonić setWillNotDraw(false) z 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"); 
} 

i nazywając invalidate z onTouchEvent:

public boolean onTouch(View v, MotionEvent event) { 

    invalidate(); 
    return true; 
} 
Powiązane problemy