Wie ermittle ich die Standard-Orientierung der Kamera-Vorschau-Frames?

Ich versuche (wieder), die Kamera-Vorschau-Logik zu erstellen, die eigentlich richtig funktioniert, für alle Szenarien :

  • Jedes Gerät: Telefon, Tablette, Toaster, was auch immer
  • Jede Kamera: nach vorne gerichtet, nach hinten gerichtet, seitlich gerichtet, hundebündig, was auch immer
  • android.hardware.Camera und android.hardware.camera2
  • Porträt- und Landschaftsgeräteorientierungen

Da meine minSdkVersion 15 ist und da ich mich nicht besonders um Leistung TextureView , versuche ich, eine TextureView . Und nach dem Rat der Fadden an Orten wie hier und hier , versuche ich setTransform() auf diesem TextureView mit einer geeigneten Matrix , die:

  • Wie aktualisiere ich den Benachrichtigungstext für einen Vordergrunddienst in Android?
  • Stream Android Screencast auf PC
  • Ist Android unterstützt JDBC
  • Youwave für Android in Remote-Desktop-Umgebung mit Thin Client
  • Android und SQLite: Wenn Sie Semikolons verwenden, um Anweisungen zu beenden?
  • Warum gibt es verschiedene Gelegenheiten für aktive und inaktive Ikonen im Materialdesign?
    • Orientiert die Vorschau ordnungsgemäß und berücksichtigt die Geräteorientierung
    • TextureView die TextureView vollständig, auf Kosten des Zuschneidens, wo das TextureView Seitenverhältnis nicht mit dem Vorschau-Frame-Seitenverhältnis übereinstimmt
    • Dehnt das Bild nicht aus, so dass eine Vorschau eines quadratischen Gegenstandes (zB ein 3 "quadratisches Post-It Note®) in der Vorschau ein Quadrat zeigt

    In meinem Fall füllt die TextureView den Bildschirm, abzüglich der Statusleiste und der Navigationsleiste.

    Beginnend mit der adjustAspectRatio() von PlayMovieActivity.java , habe ich jetzt:

      private void adjustAspectRatio(int videoWidth, int videoHeight, int rotation) { if (iCanHazPhone) { int temp=videoWidth; videoWidth=videoHeight; videoHeight=temp; } int viewWidth=getWidth(); int viewHeight=getHeight(); double aspectRatio=(double)videoHeight/(double)videoWidth; int newWidth, newHeight; if (getHeight()>(int)(viewWidth*aspectRatio)) { newWidth=(int)(viewHeight/aspectRatio); newHeight=viewHeight; } else { newWidth=viewWidth; newHeight=(int)(viewWidth*aspectRatio); } int xoff=(viewWidth-newWidth)/2; int yoff=(viewHeight-newHeight)/2; Matrix txform=new Matrix(); getTransform(txform); float xscale=(float)newWidth/(float)viewWidth; float yscale=(float)newHeight/(float)viewHeight; txform.setScale(xscale, yscale); switch(rotation) { case Surface.ROTATION_90: txform.postRotate(270, newWidth/2, newHeight/2); break; case Surface.ROTATION_270: txform.postRotate(90, newWidth/2, newHeight/2); break; } txform.postTranslate(xoff, yoff); setTransform(txform); } 

    Hier sind videoWidth und videoHeight die Größe der videoHeight , und die Methode selbst ist auf einer Unterklasse von TextureView . Ich rufe diese Methode an, wenn ich festgestellt habe, was die Kamera-Vorschaugröße ist und nachdem die TextureView selbst verkleinert wurde.

    Dies scheint nahe, aber nicht ganz richtig zu sein. Besonders der iCanHazPhone Hack – das iCanHazPhone der Video-Breite und iCanHazPhone – ist ein Stab im Dunkeln, denn ohne dieses, während ein SONY Tablet Z2 gut funktioniert, entpuppt sich ein Nexus 5 schrecklich (gestreckte Vorschau, die den Bildschirm nicht füllt).

    Mit iCanHazPhone auf true , bekomme ich gute Ergebnisse auf einem Nexus 5:

    Nexus 5, Camera2 Vorschau, Landschaft, rückseitige Kamera

    Nexus 5, Camera2 Vorschau, Portrait, rückseitige Kamera

    Mit iCanHazPhone auf false , bekomme ich Sachen wie:

    Nexus 5, Camera2 Vorschau, Porträt, rückseitige Kamera, gestreckt

    Ähnlich, mit iCanHazPhone auf false , bekomme ich gute Ergebnisse auf einem SONY Tablet Z2:

    SONY Tablet Z2, Camera2 Vorschau, Landschaft, rückseitige Kamera

    Aber wenn ich es zum true , bekomme ich:

    SONY Tablet Z2, Camera2 Vorschau, Landschaft, rückseitige Kamera, gestreckt

    Meine aktuelle Theorie ist, dass verschiedene Geräte unterschiedliche Standard-Kamera-Orientierungen haben, und je nach dieser Standard-Orientierung muss ich die Vorschau Breite und Höhe in meine Berechnungen zu drehen.

    Also, die Fragen:

    1. Ist die Kamera garantiert (so viel wie alles, was Android-Hardware beinhaltet), um eine Standard-Orientierung zu haben, die mit der Standard-Geräteorientierung übereinstimmt? Zum Beispiel funktioniert ein Nexus 9 ordnungsgemäß mit iCanHazPhone auf true , was darauf hinweist, dass es nicht Telefon vs. Tablet sondern Standard-Portrait vs Standard-Landschaft ist.

    2. Gibt es einen besseren Umgang mit diesem?

  • Wie bekomme ich ein Schlüssel / Wert-Paar aus SharedPreferences?
  • IndexOutOfBoundsException: charAt: 0> = Länge 0 auf einigen Versionen von Android
  • Android: LibGDX 2D Spiel Speicher Verbrauch
  • Was sind die Vor- und Nachteile der Verwendung von Phonegap und Titanium?
  • Verwenden der Unterstützungsaktion bar home aktiviert
  • Stoppen Sie den Internet-Zugang auf dem Emulator Android
  • 2 Solutions collect form web for “Wie ermittle ich die Standard-Orientierung der Kamera-Vorschau-Frames?”

    Beantworten Sie beide Fragen: Verwenden Sie die Sensororientierung, die von den Camera / Camera2 APIs zur Verfügung gestellt wird, um Ihr Vorschaubild anzupassen.

    Um die relative Kameradrehung auf den Bildschirm zu berechnen (was zur Umwandlung Ihrer Vorschau verwendet werden kann) benutze ich:

     static int getRelativeImageOrientation(int displayRotation, int sensorOrientation, boolean isFrontFacing, boolean compensateForMirroring) { int result; if (isFrontFacing) { result = (sensorOrientation + displayRotation) % 360; if (compensateForMirroring) { result = (360 - result) % 360; } } else { result = (sensorOrientation - displayRotation + 360) % 360; } return result; } 

    Wo displayRotation die aktuelle Display-Drehung ist:

     static int getDisplayRotation(Context context) { WindowManager windowManager = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); int rotation = windowManager.getDefaultDisplay().getRotation(); switch (rotation) { case Surface.ROTATION_0: return 0; case Surface.ROTATION_90: return 90; case Surface.ROTATION_180: return 180; case Surface.ROTATION_270: return 270; } return 0; } 

    SensorOrientation für das Vermächtnis Kamera:

     Camera.CameraInfo.orientation 

    Und für die Kamera2:

     CameraCharacteristics#get(CameraCharacteristics.SENSOR_ORIENTATION) 

    Sie sollten falsch für compansateForMirror übergeben, wenn Sie die Kamera-Vorschau-Orientierung berechnen und bei der Berechnung der Legacy-Kamera-JPG-Orientierung übergeben.

    Ich habe das über eine Reihe von Geräten getestet – es scheint zu funktionieren, obwohl ich nicht garantieren kann, dass dies kugelsicher ist;

    Sie können hier meine Antwort zur Bildausrichtung überprüfen. Nur Sie müssen die richtige Oberflächendrehung setzen.

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.