TextureView上的Xamarin.Android相机被拉伸

时间:2017-08-18 10:01:20

标签: android xamarin xamarin.android

我试图实现我自己的相机视图,例如来自" SnapChat"的相机。来自Xamarin.Forms我很难理解我遇到的问题。有没有办法保持全屏并从相机视图中删除拉伸。

来自Xamarin.Forms,您可以轻松更改XAML中图像的外观,我无法在Xamarin.Android中找到任何类似的属性。有某种财产吗?

目前正在测试三星S8 +。

相机视图的工作方式与预期相似(拍照),但视图是拉伸的图像,您可以在此处看到enter image description here

这是我的查看代码

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

这是

背后的代码
 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
    }

1 个答案:

答案 0 :(得分:1)

尝试在onMeasure中获得宽高比:

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

检查链接Camera Preview StretchedCamera Preview

尝试原始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);
            }
        }

检查此链接:

Camera Preview Stretched on few Devices

希望这可以帮助你。