2017-08-18 1 views
0

Ich versuche, meine eigene Kameraansicht wie die Kamera von "SnapChat" zu implementieren. Ich komme aus Xamarin.Forms Ich habe eine wirklich harte Zeit, um das Problem zu verstehen, das ich habe. Gibt es eine Möglichkeit, den gesamten Bildschirm beizubehalten und den Stretch aus der Kameraansicht zu entfernen?Xamarin.Android Kamera auf TextureView immer gestreckt

Kommend von Xamarin.Forms können Sie leicht den Aspekt des Bildes im XAML ändern, ich konnte keine ähnliche Eigenschaft in Xamarin.Android finden. Gibt es eine Art von Eigentum?

Derzeit testen auf Samsung S8 +.

Die Kamera-Ansicht funktioniert wie erwartet (Aufnehmen von Bildern), aber die Aussicht ist Bild Stretched Sie hier sehen können enter image description here

dies meine Ansicht Code ist

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
    <TextureView 
     android:id="@+id/textureView" 
     android:layout_marginTop="-95dp" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"/> 
    <Button 
     android:id="@+id/toggleFlashButton" 
     android:layout_width="37dp" 
     android:layout_height="37dp" 
     android:layout_gravity="top|left" 
     android:layout_marginLeft="25dp" 
     android:layout_marginTop="25dp" 
     android:background="@drawable/NoFlashButton" /> 
    <Button 
     android:id="@+id/switchCameraButton" 
     android:layout_width="35dp" 
     android:layout_height="26dp" 
     android:layout_gravity="top|right" 
     android:layout_marginRight="25dp" 
     android:layout_marginTop="25dp" 
     android:background="@drawable/ToggleCameraButton" /> 
    <Button 
     android:id="@+id/takePhotoButton" 
     android:layout_width="65dp" 
     android:layout_height="65dp" 
     android:layout_marginBottom="15dp" 
     android:layout_gravity="center|bottom" 
     android:background="@drawable/TakePhotoButton" /> 
</FrameLayout> 

und dies ist der Code hinter

public class CameraPage : PageRenderer, TextureView.ISurfaceTextureListener { 

     #region Fields 

     private Activity activity; 
     private Camera camera; 
     private CameraFacing cameraType; 

     private bool flashOn; 

     private byte[] imageBytes; 
     private SurfaceTexture surfaceTexture; 
     private Button switchCameraButton; 
     private Button takePhotoButton; 
     private TextureView textureView; 
     private Button toggleFlashButton; 
     private View view; 
     #endregion 

     #region Functions 

     public void OnSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 
      try { 
       camera = Camera.Open((int)cameraType); 

       textureView.LayoutParameters = new FrameLayout.LayoutParams(width, height, GravityFlags.FillVertical); 
       surfaceTexture = surface; 
       camera.SetPreviewTexture(surface); 
       PrepareAndStartCamera(); 
      } 
      catch (Exception ex) { 
       System.Diagnostics.Debug.WriteLine(ex.Message); 
       System.Diagnostics.Debug.WriteLine(ex.StackTrace); 
      } 
     } 

     public bool OnSurfaceTextureDestroyed(SurfaceTexture surface) { 
      try { 
       camera.StopPreview(); 
       camera.Release(); 
       return true; 
      } 
      catch (Exception ex) { 
       System.Diagnostics.Debug.WriteLine(ex.Message); 
       System.Diagnostics.Debug.WriteLine(ex.StackTrace); 
      } 
      return true; 
     } 

     public void OnSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 
      PrepareAndStartCamera(); 
     } 

     public void OnSurfaceTextureUpdated(SurfaceTexture surface) { 

     } 

     protected override void OnElementChanged(ElementChangedEventArgs<Page> e) { 
      base.OnElementChanged(e); 

      if (e.OldElement != null || Element == null) 
       return; 

      try { 
       activity = Context as Activity; 
       view = activity.LayoutInflater.Inflate(Resource.Layout.CameraLayout, this, false); 
       cameraType = CameraFacing.Back; 

       textureView = view.FindViewById<TextureView>(Resource.Id.textureView); 
       textureView.SurfaceTextureListener = this; 

       takePhotoButton = view.FindViewById<Button>(Resource.Id.takePhotoButton); 
       takePhotoButton.Click += TakePhotoButtonTapped; 

       switchCameraButton = view.FindViewById<Button>(Resource.Id.switchCameraButton); 
       switchCameraButton.Click += SwitchCameraButtonTapped; 

       toggleFlashButton = view.FindViewById<Button>(Resource.Id.toggleFlashButton); 
       toggleFlashButton.Click += ToggleFlashButtonTapped; 

       AddView(view); 
      } 
      catch (Exception ex) { 
       System.Diagnostics.Debug.WriteLine(ex.Message); 
       System.Diagnostics.Debug.WriteLine(ex.StackTrace); 
      } 
     } 



     protected override void OnLayout(bool changed, int l, int t, int r, int b) { 
      try { 
       base.OnLayout(changed, l, t, r, b); 

       var msw = MeasureSpec.MakeMeasureSpec(r - l, MeasureSpecMode.AtMost); 
       var msh = MeasureSpec.MakeMeasureSpec(b - t, MeasureSpecMode.AtMost); 

       view.Measure(msw, msh); 
       view.Layout(0, 0, r - l, b - t); 
      } 
      catch (Exception ex) { 
       System.Diagnostics.Debug.WriteLine(ex.Message); 
       System.Diagnostics.Debug.WriteLine(ex.StackTrace); 
      } 
     } 

     private void PrepareAndStartCamera() { 
      try { 
       camera.StopPreview(); 

       var display = activity.WindowManager.DefaultDisplay; 

       if (display.Rotation == SurfaceOrientation.Rotation0) camera.SetDisplayOrientation(90); 

       if (display.Rotation == SurfaceOrientation.Rotation270) camera.SetDisplayOrientation(180); 

       camera.StartPreview(); 
      } 
      catch (Exception ex) { 
       System.Diagnostics.Debug.WriteLine(ex.Message); 
       System.Diagnostics.Debug.WriteLine(ex.StackTrace); 
      } 
     } 

     private void SwitchCameraButtonTapped(object sender, EventArgs e) { 
      try { 
       if (cameraType == CameraFacing.Front) { 
        cameraType = CameraFacing.Back; 

        camera.StopPreview(); 
        camera.Release(); 
        camera = Camera.Open((int)cameraType); 
        camera.SetPreviewTexture(surfaceTexture); 
        PrepareAndStartCamera(); 
       } 
       else { 
        cameraType = CameraFacing.Front; 

        camera.StopPreview(); 
        camera.Release(); 
        camera = Camera.Open((int)cameraType); 
        camera.SetPreviewTexture(surfaceTexture); 
        PrepareAndStartCamera(); 
       } 
      } 
      catch (Exception ex) { 
       System.Diagnostics.Debug.WriteLine(ex.Message); 
       System.Diagnostics.Debug.WriteLine(ex.StackTrace); 
      } 
     } 

     private void ToggleFlashButtonTapped(object sender, EventArgs e) { 
      try { 
       flashOn = !flashOn; 
       if (flashOn) { 
        if (cameraType == CameraFacing.Back) { 
         toggleFlashButton.SetBackgroundResource(Resource.Drawable.FlashButton); 
         cameraType = CameraFacing.Back; 

         camera.StopPreview(); 
         camera.Release(); 
         camera = Camera.Open((int)cameraType); 
         var parameters = camera.GetParameters(); 
         parameters.FlashMode = Camera.Parameters.FlashModeTorch; 
         camera.SetParameters(parameters); 
         camera.SetPreviewTexture(surfaceTexture); 
         PrepareAndStartCamera(); 
        } 
       } 
       else { 
        toggleFlashButton.SetBackgroundResource(Resource.Drawable.NoFlashButton); 
        camera.StopPreview(); 
        camera.Release(); 

        camera = Camera.Open((int)cameraType); 
        var parameters = camera.GetParameters(); 
        parameters.FlashMode = Camera.Parameters.FlashModeOff; 
        camera.SetParameters(parameters); 
        camera.SetPreviewTexture(surfaceTexture); 
        PrepareAndStartCamera(); 
       } 
      } 
      catch (Exception ex) { 
       System.Diagnostics.Debug.WriteLine(ex.Message); 
       System.Diagnostics.Debug.WriteLine(ex.StackTrace); 
      } 
     } 

     private async void TakePhotoButtonTapped(object sender, EventArgs e) { 
      try { 
       camera.StopPreview(); 
       DialogService.ShowLoading("Capturing..."); 

       var image = textureView.Bitmap; 
       using (var imageStream = new MemoryStream()) { 
        await image.CompressAsync(Bitmap.CompressFormat.Png, 75, imageStream); 
        image.Recycle(); 
        imageBytes = imageStream.ToArray(); 
       } 


       camera.StartPreview(); 
       await App.NavigationController.PushAsync(new ImagePreviewView(imageBytes)); 
       DialogService.HideLoading(); 
      } 
      catch (Exception ex) { 
       System.Diagnostics.Debug.WriteLine(ex.Message); 
       System.Diagnostics.Debug.WriteLine(ex.StackTrace); 
      } 
     } 
     #endregion 
    } 
+2

1) Kameras von verschiedenen OEMs haben unterschiedliche Seitenverhältnisse. 2) Ich sehe nicht, wo Sie die Vorschaugrößen der Kamera bekommen, die benötigt werden, um die Ausgabe richtig zu transformieren, es gibt viele Beispiele, die herum schweben: zB https://Stackoverflow.com/a/17878832/4984832 – SushiHangover

+0

Ich habe getestet Die App auf verschiedenen Geräten und die Probleme bestehen auf einer Vielzahl von Geräten. Das ist mein Problem, dass ich keine Funktion oder eine Eigenschaft finden kann, wo ich die Vorschaugröße einstellen kann. –

+0

Holen Sie sich die Vorschaugröße und verwandeln Sie sie in die TextureView, lesen Sie die vorhandenen Antworten (es gibt viele ;-): https://StackOverflow.com/search?q=android+camera+preview+aspect+Ratio+textureview – SushiHangover

Antwort

1

Versuch das Seitenverhältnis in onMeasure zu erhalten:

protected void onMeasure(int widthSpec, int heightSpec) {//} 

Überprüfen Sie die Links, Camera Preview Stretched, Camera Preview

versuchen diese ursprüngliche here

protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec) 
     { 
      // We purposely disregard child measurements because act as a 
      // wrapper to a SurfaceView that centers the camera preview instead 
      // of stretching it. 
      int width = ResolveSize(SuggestedMinimumWidth, widthMeasureSpec); 
      int height = ResolveSize(SuggestedMinimumHeight, heightMeasureSpec); 
      SetMeasuredDimension(width, height); 

      if (_mSupportedPreviewSizes != null) 
      { 
       _mPreviewSize = GetOptimalPreviewSize(_mSupportedPreviewSizes, width, height); 
      } 
     } 

prüfen Sie diesen Link:

Camera Preview Stretched on few Devices

Hope this Sie helfen können.

+0

Vielen Dank für Ihre Antwort. Basierend auf Ihren Links habe ich meinen Code aktualisiert, kann ihn jedoch immer noch nicht ausführen :(Würde es Ihnen etwas ausmachen, sich meinen Code anzusehen? Https://pastebin.com/p2TY717Y –

+0

@iNCEPTiON_okay lassen Sie mich Ihren Code überprüfen. – Janmejoy

+0

@iNCEPTiON_try mit der Änderung der ASPECT_TOLERANCE mit Vorschau sizes.link hier https://stackoverflow.com/questions/17804309/android-camera-preview-wrong-aspect-ratio – Janmejoy

Verwandte Themen