it-swarm.com.de

Die Kameraanzeige / Vorschau im Vollbildmodus behält das Seitenverhältnis nicht bei - das Bild ist verzerrt und gestreckt, um auf den Bildschirm zu passen

Ich habe eine kleine Anwendung zum Anzeigen der Kameravorschau im Vollbildmodus entwickelt. Ich benutze dafür die Kamera-API.

Dies ist das Aktivitätslayout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
              Android:orientation="vertical"
              Android:layout_width="match_parent"
              Android:layout_height="match_parent">

    <!-- This is the container for the camera preview screen -->
    <FrameLayout Android:id="@+id/camera_preview"
                 Android:layout_width="wrap_content"
                 Android:layout_height="wrap_content"/>
</LinearLayout>

Wenn sich das Gerät im Hochformat befindet, wird die Anzeige vertikal skaliert, um der Höhe des Gerätebildschirms zu entsprechen. Das Seitenverhältnis stimmt also nicht mit dem von der nativen Kamera überein. Dies sind 2 Bilder, die besser erklären, was ich sage:

enter image description hereenter image description here

Das erste Bild wird mit einem nativen Kameragerät aufgenommen. Das zweite Bild wird mit meiner App erstellt, mit der Kamera im Vollbildmodus - das Bild wird verzerrt und gestreckt, um auf den Bildschirm zu passen.

Ich benötige eine Vollbildvorschau der Kamera, unabhängig von der Vorschaugröße, die von getSupportedPreviewSizes() mehod und ohne Verzerrung angegeben wird. Gibt es eine Möglichkeit, dies zu erreichen? Gibt es eine Möglichkeit, das richtige Seitenverhältnis beizubehalten, wenn sich die Kameravorschau im Vollbildmodus befindet? Ich habe erwartet, dass dies vom Betriebssystem automatisch durchgeführt wird - das Bild wird auf die angeforderte Auflösung zugeschnitten, während das Seitenverhältnis beibehalten wird, aber das passiert nicht.

Ich habe versucht, das SurfaceView größer als das Display zu machen (im Anschluss an diese Frage: Anpassen einer Kameravorschau an ein SurfaceView, das größer als das Display ist ), aber in meinem Fall ist dies seitdem nicht mehr in Ordnung Ich nehme Schnappschüsse auf (6 Bilder/Sekunde) und das ist nicht das, was der Benutzer auf dem Bildschirm sieht (der Rahmen enthält die gesamte Kameravorschau, auch wenn nicht alles auf dem Bildschirm sichtbar ist).

Ich habe hier gepostet: https://www.dropbox.com/s/3d52xt8kazynsae/CameraFullScreen.7z?v=0mcn das gesamte Projekt, das ich gemacht habe.

Jede Idee/Lösung ist für mich mehr als wichtig. Danke vielmals.

================================================ =====================

Update wegen ss1271 Antwort:

Ich werde ein wenig die Auflösungen analysieren, die Sie oben für Samsung Galaxy Ace II geschrieben haben.

ich. Bildschirmauflösung: 480x800 - Seitenverhältnis 3: 5 = 0,6

II. getSupportedPreviewSizes - Ich bin mir fast sicher, dass diese Werte von der Rückkamera stammen. Nachfolgend finden Sie das Seitenverhältnis für diese Auflösungen:

   2560x1920   - 0,75

   2560x1536   - 0,60

   2048x1536   - 0,75

   2048x1232   - 0,60

   960x720     - 0,75

   640x480     - 0,75

Ihre Methode gibt also ein Size zurück, das 2560x1536 oder 2048x1232 entspricht - diese haben dasselbe Seitenverhältnis wie die Bildschirmauflösung und verwenden diese Werte verzerren das Bild nicht. Das Problem für mich ist, dass ich keine so großen Auflösungen verwenden kann, da ich 6 Bilder/Sekunde aufnehme und diese mit einer niedrigeren Auflösung speichern muss.

Ich werde im Folgenden einige Ergebnisse von einem Samsung S2 Gerät vorstellen:

ich. Bildschirmauflösung: 480 x 800 - Seitenverhältnis 3: 5 = 0,6

II. Rückfahrkamera
ein). getSupportedPreviewSizes:

800 / 480   - 480/800 = 0,60
800 / 450   - 450/800 = 0,56
720 / 480   - 0,66 
640 / 480   - 0,75
352 / 288   - 0,81
320 / 240   - 0,75
176 / 144   - 0,81

b). Native Kameraauflösungen:

3264 / 2448  - 0,75  - not full screen
3264 / 1968  - 0,60  - FULL SCREEN (since has the same aspect ratio as device screen)
2048 / 1536  - 0,75  - not full screen
2048 / 1232  - 0,60  - FULL SCREEN (same aspect ratio as device screen)
800 / 480    - 0,60  - FULL SCREEN (same aspect ratio as device screen)
640 / 480    - 0, 75 - not full screen

III. Frontkamera
ein). getSupportedPreviewSizes:

640 / 480   - 0,75
352 / 288   - 0,81
320 / 240   - 0,75
176 / 144   - 0,81

b). Die native Kamera ist nicht im Vollbildmodus und ich kann keine Auflösung auswählen - die Option ist deaktiviert.

Bei S2, Rückfahrkamera, frage ich mich, warum die Methode getSupportedPreviewSizes() nicht die gleichen Auflösungen liefert wie die native Kamera oder die von der nativen Kamera angezeigten Bildgrößen? Ich frage mich, warum ich keine Optionen wie 3264/1968, 2048/1232 habe, die von der Methode getSupportedPreviewSizes() angegeben wurden. : enter image description here

30
Paul

Kurz gesagt, Sie können eine Kameravorschau im Vollbildmodus erstellen. Sie müssen jedoch die entsprechenden Größen unter den unterstützten Vorschaugrößen nur dann selbst ermitteln, wenn Sie eine benutzerdefinierte Kameravorschau wünschen.

Für deine Frage gilt laut Android Developers - Camera

Wenn Sie eine bestimmte Größe für Ihre Kameravorschau festlegen möchten, stellen Sie diese in der surfaceChanged() -Methode ein, wie in den obigen Kommentaren angegeben. Beim Einstellen der Vorschaugröße müssen Sie Werte aus getSupportedPreviewSizes() verwenden . Legen Sie in der setPreviewSize() -Methode keine willkürlichen Werte fest .

Es schien, dass Sie die gewünschte Größe nicht manuell übergeben können, außer den von getSupportedPreviewSizes() bereitgestellten Größen. Wenn Sie die von Ihrer Telefonkamera unterstützten Größen genauer untersuchen, werden Sie feststellen, dass das Verhältnis der unterstützten Größen möglicherweise nicht genau dem Verhältnis Ihres Bildschirms entspricht.

Zum Beispiel hat Samsung Galaxy Ace II einen Bildschirm mit einer Auflösung von 480x800, durch Lesen des von getSupportedPreviewSizes() zurückgegebenen Size unterstützt seine Kamera:

2560 x 1920

2560 x 1536

2048 x 1536

2048 x 1232

960 x 720

640 x 480

und wenn Sie Ihre Kameravorschau im Vollbildmodus korrekt (ohne Dehnung) anzeigen möchten, müssen Sie das geeignete Verhältnis in diesen unterstützten Vorschaugrößen berechnen, vergleichen und anwenden.

Die Implementierung einer geeigneten Vorschaugröße ist nicht so kompliziert. Eine gebräuchliche Methode dafür wäre:

    /**
     * Calculate the optimal size of camera preview
     * @param sizes
     * @param w
     * @param h
     * @return
     */
    private Size getOptimalSize(List<Size> sizes, int w, int h) {

        final double ASPECT_TOLERANCE = 0.2;        
        double targetRatio = (double) w / h;         
        if (sizes == null)             
            return null;          
        Size optimalSize = null;         
        double minDiff = Double.MAX_VALUE;          
        int targetHeight = h;          
        // Try to find an size match aspect ratio and size         
        for (Size size : sizes) 
        {             
//          Log.d("CameraActivity", "Checking size " + size.width + "w " + size.height + "h");            
            double ratio = (double) size.width / size.height;            
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)                
                continue;             
            if (Math.abs(size.height - targetHeight) < minDiff) 
            {                 
                optimalSize = size;                 
                minDiff = Math.abs(size.height - targetHeight);             
            }         
        }          
        // Cannot find the one match the aspect ratio, ignore the requirement     

        if (optimalSize == null)
        {
            minDiff = Double.MAX_VALUE;             
            for (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff)
                {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight); 
                }
            }
        }

        SharedPreferences previewSizePref;
        if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
            previewSizePref = getSharedPreferences("PREVIEW_PREF",MODE_PRIVATE);
        } else {
            previewSizePref = getSharedPreferences("FRONT_PREVIEW_PREF",MODE_PRIVATE);
        }

        SharedPreferences.Editor prefEditor = previewSizePref.edit();
        prefEditor.putInt("width", optimalSize.width);
        prefEditor.putInt("height", optimalSize.height);

        prefEditor.commit();

//      Log.d("CameraActivity", "Using size: " + optimalSize.width + "w " + optimalSize.height + "h");            
        return optimalSize;     
    }

Ähnliches können Sie auch tun, um die geeigneten Kameragrößen (die Ausgabebildgröße) zu ermitteln.

Hinweis: Ich habe die Originalversion des obigen Codes aus dem Internet gefunden und einige Änderungen/Optimierungen für meinen eigenen Zweck vorgenommen.

Bitte lassen Sie mich wissen, ob dies für Sie funktioniert.

27
dumbfingers

Ich hatte das gleiche Problem in der Camera2-API. Ich habe Vorschaugröße und Seitenverhältnis der Geräte verwendet, um das Problem zu lösen. Sie können dasselbe auch mit Ihrer Kamera-API tun.

0
Ronak Patel