2014-09-18 6 views
5

Ich würde gerne wissen, wie ein Rechteck in bestimmter Position und Größe zu zeichnen.Zeichnen Rechteck auf SurfaceView

Ich habe ein paar Versuche und Beispiele hier und im Internet versucht, aber nichts hat für mich funktioniert.

Ich benutze ein SurfaceView und SurfaceHolder, um die Kameravorschau zu halten.

Ich möchte nur ein Rechteck zeichnen, wenn der Benutzer auf dem Bildschirm berühren.

Ich möchte keine externe Bibliothek verwenden und wenn ich versuche, die Leinwand aus dem Halter zu bekommen, bekomme ich null.

Für jetzt gibt es keinen Code, denn nichts funktioniert für mich, wenn jemand eine Ahnung hat, wie es geht, werde ich es versuchen. Diese

ist das, was ich habe schon versucht:

Link 1

Link 2

Link 3

Dank für die Hilfe!

+0

Eine bestimmte SurfaceView-Oberfläche kann nur einen "Producer" haben. Da die Kamera darauf zeichnet, kann man nicht mit einem Canvas darauf zeichnen. Sie müssen auf einer anderen Oberfläche zeichnen; Am effizientesten wäre es, eine transparente Ansicht zu verwenden. Ein anderer Ansatz wäre, die Kamera zu einer SurfaceTexture zu senden und sie mit GLES zu rendern, was Ihnen volle Freiheit gibt. Siehe z.B. "Textur von Kamera" auf https://github.com/google/grafika. – fadden

+0

Können Sie mir ein Beispiel geben, wie Sie eine transparente Ansicht erstellen? Alles, was ich gefunden habe, sind Beispiele, die nur ein Rechteck zeigen und die Ansicht als * setContentView (drawView); * so einstellen, dass ich die Kamera nicht sehen kann. – user2235615

Antwort

5

Ok, dank Fadden fand ich die einfachste Lösung (zumindest für mich).

Zuerst habe ich erstellt eine andere Oberfläche Ansicht und meine XML-Datei wie folgt aussehen:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/scrollView1" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    xmlns:tools="http://schemas.android.com/tools" 
    xmlns:opencv="http://schemas.android.com/apk/res-auto" 
    android:layout_gravity="left|top"> 
     <RelativeLayout 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:orientation="vertical" > 

        <SurfaceView 
         android:layout_alignParentTop="true" 
         android:id="@+id/CameraView" 
         android:layout_width="match_parent" 
         android:layout_height="match_parent" /> 
        <SurfaceView 
         android:layout_alignParentTop="true" 
         android:id="@+id/TransparentView" 
         android:layout_width="match_parent" 
         android:layout_height="match_parent" /> 
      </RelativeLayout> 
</RelativeLayout> 

Und als ich einen anderen Halter für die neue Oberfläche geschaffen, das ist ein Teil meiner Java-Code:

protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_video_capture); 
     // Create first surface with his holder(holder) 
     cameraView = (SurfaceView)findViewById(R.id.CameraView); 
     cameraView.setOnTouchListener(onTouchListner); 

     holder = cameraView.getHolder(); 
     holder.addCallback(this); 
     holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

     // Create second surface with another holder (holderTransparent) 
     transparentView = (SurfaceView)findViewById(R.id.TransparentView); 

     holderTransparent = transparentView.getHolder(); 
     holderTransparent.setFormat(PixelFormat.TRANSPARENT); 
     holderTransparent.addCallback(callBack); 
     holderTransparent.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 

Endlich habe ich eine Methode ‚DrawFocusRect‘

private void DrawFocusRect(float RectLeft, float RectTop, float RectRight, float RectBottom, int color) 
{ 

    canvas = holderTransparent.lockCanvas(); 
    canvas.drawColor(0,Mode.CLEAR); 
    //border's properties 
    paint = new Paint(); 
    paint.setStyle(Paint.Style.STROKE); 
    paint.setColor(color); 
    paint.setStrokeWidth(3); 
    canvas.drawRect(RectLeft, RectTop, RectRight, RectBottom, paint); 


    holderTransparent.unlockCanvasAndPost(canvas); 
} 

genannt implementieren Wie Sie sehen können, habe ich klar die Leinwand jedes Mal, wenn ich dies nicht mache, wird die Oberfläche zusätzlich mehr Rechtecke auf einander anzeigen. Diese

ist, wie ich auf diese Methode aufrufen, von einem 'OnTouchListener' Veranstaltung:

OnTouchListener onTouchListner = new OnTouchListener() { 

     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
        RectLeft = event.getX() - 100; 
        RectTop = event.getY() - 100 ; 
        RectRight = event.getX() + 100; 
        RectBottom = event.getY() + 100; 
        DrawFocusRect(RectLeft , RectTop , RectRight , RectBottom , Color.BLUE); 
      } 
     }; 

Hope this für jemand anderen hilfreich sein würde.

+4

FWIW, wenn sich die SurfaceView-Flächen überlappen, müssen Sie ihnen mithilfe der SurfaceHolder-API unterschiedliche Tiefen (Z-Aufträge) zuweisen. In Grafikas Multi-Surface-Test (https://github.com/google/grafika/blob/master/src/com/android/grafika/MultiSurfaceActivity.java) sehen Sie eine Aktivität mit drei überlappenden, von Software gerenderten SurfaceViews. – fadden

+0

Eigentlich funktionierte der obige Code für mich, aber Sie haben Recht. Es ist besser, mit dem Zorder zu arbeiten. – user2235615

+0

Ja @fadden, ich konnte einfach nicht erreichen, das Rechteck zu arbeiten, als den Z-Wert zu setzen, wie du erwähnt hast, und es hat perfekt funktioniert, danke. – webmaster