2012-07-04 5 views
23

Ich habe eine Android-Anwendung, die eine Vollbildvorschau der Kamera unabhängig von der Vorschaugröße von getSupportedPreviewSizes() ohne Verzerrung erforderlich ist. Ich erwarte, dass dies die Vorschau um einen bestimmten Betrag in Höhe oder Breite beschneidet, aber das betrifft mich nicht. Der Grund, warum ich dies versuche, liegt darin, dass bestimmte Android-Kameras (z. B. Samsung Galaxy SII-Frontkamera) keine Vorschaubilder mit dem gleichen Seitenverhältnis wie das Display zurückgeben und daher gestreckt und abgeschnitten werden müssen.Anpassen einer Kameravorschau an ein SurfaceView, das größer als das Display ist

Ist es möglich, die Kameravorschau vollständig auf eine Ansicht größer als die Anzeigegröße zu vergrößern? Es ist möglich, das SurfaceView größer als die zurückgegebenen Vorschaupixeldimensionen zu gestalten, indem Sie einfach die Layoutparameter der Oberflächenansicht auf match_parent setzen. Dies führt jedoch zu Verzerrungen in einige Richtungen und ist nur möglich, bis die Vorschau die Anzeige füllt. Dies scheint darauf hinzuweisen, dass eine Vorschau außerhalb des Displays unmöglich ist und die Hardware (oder das Betriebssystem) ein solches Verhalten einschränkt.

Es gibt another question zum Thema, aber diese Frage behauptet, dass es nicht möglich ist, ein SurfaceView größer als die Bildschirmdimensionen zu erstellen, was falsch ist, wie ich mit der Protokollierung gefunden habe. Wie dem auch sei, die Kameravorschau kann jedoch nicht auf die volle Größe eines riesigen SurfaceViews wachsen.

Mein Versuch:

Ich habe ein relativ Layout, in ihm einen FrameLayout und innerhalb dass ich eine Surface. Die Breite des gesamten relativen Layouts ist unterhalb von 635 dpi eingestellt, was der doppelten Bildschirmgröße des Geräts entspricht. Die FrameLayout Spiele in dieser Dimensionierung und damit auch die Surface (programmatisch später hinzugefügt)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/camera_activity_layout" 
    android:layout_width="635dp" 
    android:layout_height="match_parent" > 

    <FrameLayout 
     android:id="@+id/camera_preview" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 
    </FrameLayout> 

</RelativeLayout> 

Im folgenden ist der Code, der bekommt und legt die Vorschaugröße. Hier möchte ich die Kameravorschau erweitern, um das gesamte FrameLayout (doppelte Bildschirmbreite) zu füllen. Die Ansicht wird vollständig normal angezeigt und zerstört. Daher entferne ich den Code, der nicht mit dieser speziellen Frage zu tun hat, weil er von der wesentlichen Frage ablenkt, und versuche, die Ansicht einfach und einfach auf eine größere Größe zu vergrößern.

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 

    ... 

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
     Camera.Parameters parameters = mCamera.getParameters(); 
     final DisplayMetrics dm = this.getResources().getDisplayMetrics(); 
      //getBestPreviewSize returns the best preview size, don't worry 
      //but some devices do not return one for all camera matching the aspect ratio 
     cameraSize = getBestPreviewSize(parameters, dm.heightPixels, dm.widthPixels); 

     if (cameraSize!=null) { 
      parameters.setPreviewSize(cameraSize.width, cameraSize.height); 
      mCamera.setParameters(parameters); 
     } 

     FrameLayout.LayoutParams frameParams = (FrameLayout.LayoutParams) this.getLayoutParams(); 

     frameParams.width = 800; //For argument's sake making this ~double the width of the display. Same result occurs if I use MATCH_PARENT 
     frameParams.height = LayoutParams.MATCH_PARENT; 
     this.setLayoutParams(frameParams); 

     try { 
      mCamera.setPreviewDisplay(mHolder); 
      mCamera.startPreview(); 

      Log.d("surfChange","W/H of CamPreview (child) is "+this.getWidth()+"/"+this.getHeight()+" while parent is "); 
      Log.d("surfChange","W/H of holder (child) is "+mHolder.getSurfaceFrame().width()+"/"+mHolder.getSurfaceFrame().height()+" while parent is "); 
     } catch (Exception e){ 
     } 
    } 
}; 

Ich bin besorgt darüber, dass der einzige Weg, in diesem Bemühen um erfolgreich zu sein ist zu einer openGL Oberfläche irgendwie zu machen, aber die apparently könnte in voller Farbe zu langsam sein. Es ist auch ein Schmerz, wenn die Kameravorschau einfach gestreckt und abgeschnitten werden kann.

Vielen Dank im Voraus für alle Lösungsversuche.

+0

Konnte Ihren post oncreate() - Code nachpflegen. oder wo rufen Sie die setcontentview() -Methode auf –

+0

Warum sind Sie neugierig auf diesen Code? Es war ziemlich einfach und setzte einfach die Inhaltsansicht auf das XML, das ich oben geteilt hatte. –

+0

ok, ich denke, eine Ansicht über den Fenstermanager hinaus zu erweitern, ist nicht möglich, ich suche auch in einem Ausschnitt des Videos, aber benutze alle Oberflächenansicht und benutzerdefinierte Videoansicht, ich bekomme keine, Video wird nicht über die Größe abgeschnitten –

Antwort

12

Ok, ich weiß, das ist sehr spät als Antwort, aber es ist möglich. Im Folgenden finden Sie Code aus dem Android SDK-Beispiel. der Rest des Codes zu sehen, diesen Download im Android sdk Proben zu implementieren und gehen zu Samples/android-10(one I used, could try whichever you want to target)/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.java

class PreviewSurface extends ViewGroup implements SurfaceHolder.Callback { 
... 
@Override 
protected void onLayout(boolean changed, int l, int t, int r, int b) { 
    if (changed && getChildCount() > 0) { 
     final View child = getChildAt(0); 

     final int width = r - l; 
     final int height = b - t; 

     int previewWidth = width; 
     int previewHeight = height; 
     if (mPreviewSize != null) { 
      previewWidth = mPreviewSize.width; 
      previewHeight = mPreviewSize.height; 
     } 

     // Center the child SurfaceView within the parent. 
     if (width * previewHeight > height * previewWidth) { 
      final int scaledChildWidth = previewWidth * height/previewHeight; 
      child.layout((width - scaledChildWidth)/2, 0, 
        (width + scaledChildWidth)/2, height); 
     } else { 
      final int scaledChildHeight = previewHeight * width/previewWidth; 
      child.layout(0, (height - scaledChildHeight)/2, 
        width, (height + scaledChildHeight)/2); 
     } 
    } 
} 
} 

Dieser Code soll die Vorschau auf die kleinste Abmessung passen (das nicht vermasseln die aspcect-Verhältnis) und Mitte, um schwarze Balken auf der anderen Dimension zu haben. Aber wenn Sie die > auf < drehen, werden Sie erreichen, was Sie wollen. Bsp .:

if (width * previewHeight < height * previewWidth) {...