2012-07-04 14 views
23

Mam aplikację na Androida, która musi wyświetlać podgląd pełnoekranowy niezależnie od rozmiaru podglądu podanego przez getSupportedPreviewSizes() bez zniekształceń. Spodziewam się, że przycinam podgląd o jakąś wysokość albo szerokość, ale to mnie nie dotyczy. Powodem, dla którego staram się to zrobić, jest to, że niektóre aparaty z systemem Android (np. Kamera Samsung Galaxy SII z przodu) nie zwracają żadnych podglądów o tym samym współczynniku kształtu co ekran, a zatem muszą być rozciągnięte i przycięte.Dopasowywanie podglądu kamery do SurfaceView jest większy niż wyświetlacz.

Czy można w pełni powiększyć podgląd kamery do widoku większego niż rozmiar ekranu? Możliwe jest zwiększenie SurfaceView większego niż wymiary podglądu w pikselach, które są zwracane przez proste ustawienie parametrów układu widoku powierzchni na match_parent, ale powoduje to zniekształcenie w pewnym kierunku i jest możliwe do momentu, aż podgląd wypełni ekran. Wydaje się to wskazywać, że podgląd poza ekranem jest niemożliwy, a sprzęt (lub OS) ogranicza takie zachowanie.

Istnieje another question na ten temat, ale to pytanie nie pozwala na stworzenie SurfaceView większego niż wymiary ekranu, które są błędne, jak to stwierdziłem podczas rejestrowania. Jednak wygląda na to, że podgląd kamery nie może jednak rozwinąć się do pełnego rozmiaru ogromnego SurfaceView.

moja próba:

mam względny układ, wewnątrz niej FrameLayout i wewnątrz że tworzę SurfaceView. Szerokość całego układu względnego jest ustawiona poniżej na 635dp, co jest ~ dwukrotnie większe niż rozmiar ekranu urządzenia. FrameLayout pasuje do tej zaklejanie i tak nie SurfaceView programowo (dodane później)

<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> 

Poniżej znajduje się kod, który pobiera i ustawia rozmiar podglądu. Tutaj chcę, aby podgląd kamery rozwinął się, aby wypełnić cały FrameLayout (podwójną szerokość ekranu). Widok ukazuje się i ulega całkowitemu zniszczeniu, więc usuwam kod niezwiązany z tym konkretnym pytaniem, ponieważ odciąga on od zasadniczego pytania i moją próbą łatwego i prostego rozwinięcia widoku do rozmiaru większego niż wyświetlany.

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){ 
     } 
    } 
}; 

Obawiam się, że jedynym sposobem na sukces w tym przedsięwzięciu jest jakiś sposób renderowania do powierzchni OpenGL, ale to apparently może być zbyt powolny w pełnym kolorze. Jest to również problem, jeśli podgląd kamery można po prostu rozciągnąć i przyciąć.

Z góry dziękuję za wszelkie próby rozwiązania.

+0

Czy możesz upls ur ur oncreate() kod. lub gdzie wywołujesz metodę setcontentview() –

+0

Dlaczego jesteś ciekawy tego kodu? To było całkiem proste i po prostu ustaw widok zawartości na xml, który udostępniono powyżej. –

+0

OK, więc myślę, że rozwijanie widoku poza menadżerem okien nie jest możliwe, również szukam powiększenia sekcji wideo, ale przy użyciu widoku powierzchni i niestandardowego widoku wideo nie dostaję żadnego, wideo nie jest wykadrowane poza rozmiar –

Odpowiedz

12

OK, wiem, że odpowiedź jest bardzo późna, ale jest to możliwe. Poniżej znajduje się kod z próbki Androida SDK. Aby zobaczyć resztę kodu do realizacji tego pobierania próbek Android SDK i przejdź do 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); 
     } 
    } 
} 
} 

kod ten jest przeznaczony, aby dopasować podgląd do najmniejszego wymiaru (nie robi bałagan stosunek aspcect) i w centrum, aby mieć czarne paski w drugim wymiarze. Ale jeśli przełączysz > na < zamiast tego osiągniesz to, co chcesz. Np:

if (width * previewHeight < height * previewWidth) {... 
Powiązane problemy