C# xamarin android纹理视图应用程序中的奇怪行为

C# xamarin android纹理视图应用程序中的奇怪行为,c#,android,xamarin,camera,textureview,C#,Android,Xamarin,Camera,Textureview,我正在使用一个移动应用程序(由xamarin为android开发),它能够从相机中传输数据,拍摄照片并将其保存在内存中。该应用程序可以工作,但当它部署在不同的智能手机上时,会出现一些奇怪的情况,如下图所示 它看起来很奇怪,但正如你将要看到的,在其他手机上,如华硕Zefone go和索尼xperia Z1,图像看起来很奇怪,好像物体的形状会发生变化: 这很难解释,但当我将手机从垂直模式(纵向)转到水平模式(横向)时,就会出现这种变化。所有这些,旋转屏幕功能都被禁用。这看起来像是图像中的某种失真,因

我正在使用一个移动应用程序(由xamarin为android开发),它能够从相机中传输数据,拍摄照片并将其保存在内存中。该应用程序可以工作,但当它部署在不同的智能手机上时,会出现一些奇怪的情况,如下图所示

它看起来很奇怪,但正如你将要看到的,在其他手机上,如华硕Zefone go和索尼xperia Z1,图像看起来很奇怪,好像物体的形状会发生变化:

这很难解释,但当我将手机从垂直模式(纵向)转到水平模式(横向)时,就会出现这种变化。所有这些,旋转屏幕功能都被禁用。这看起来像是图像中的某种失真,因为最初(垂直模式),对象看起来更“延伸”,最后(将手机转到水平模式)它们看起来比最初看起来更短、更胖

这是视图的AXML代码:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1">
    <TextureView
        android:id="@+id/textureView"
        android:scaleType="fitXY"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <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" />
    <ToggleButton
        android:textOff=""
        android:textOn=""
        android:checked="false"
        android:layout_width="37dp"
        android:layout_height="37dp"
        android:layout_gravity="top|left"
        android:layout_marginLeft="25dp"
        android:layout_marginTop="25dp"
        android:id="@+id/toggleFlashButton"
        android:background="@drawable/FlashButton" />
</FrameLayout>

这是一节课:

namespace CameraStream
{
    [Activity(Label = "CameraStream", MainLauncher = true, Icon = "@drawable/SendButton", Theme = "@android:style/Theme.NoTitleBar")]
    public class Activity1 : Activity, TextureView.ISurfaceTextureListener, IPictureCallback        
    {
        Android.Hardware.Camera _camera;

        TextureView _textureView;
        Button TakePictureBtn;
        ToggleButton FlashBtn;
        Bitmap UserPicture;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView(Resource.Layout.Main);
            _textureView = FindViewById<TextureView>(Resource.Id.textureView);
            _textureView.SurfaceTextureListener = this;
            TakePictureBtn = FindViewById<Button>(Resource.Id.takePhotoButton);
            TakePictureBtn.Click += TakePicture_Click;
            FlashBtn = FindViewById<ToggleButton>(Resource.Id.toggleFlashButton);
            FlashBtn.CheckedChange += Flash_Click;
        }
        private void Flash_Click(object sender, CompoundButton.CheckedChangeEventArgs e)
        {
            Globals g = Globals.getInstance;
            Android.Hardware.Camera.Parameters param = _camera.GetParameters();
            if (e.IsChecked)
            {
                g.SetFlash(true);
                FlashBtn.SetBackgroundResource(Resource.Drawable.NoFlashButton);
                param.FlashMode = Android.Hardware.Camera.Parameters.FlashModeOn;
                _camera.SetParameters(param);
            }
            else
            {
                g.SetFlash(false);
                FlashBtn.SetBackgroundResource(Resource.Drawable.FlashButton);
                param.FlashMode = Android.Hardware.Camera.Parameters.FlashModeOff;
                _camera.SetParameters(param);
            }
        }
        private void TakePicture_Click(object sender, EventArgs e)
        {
            _camera.TakePicture(null, null, this);         
        }

        public void OnSurfaceTextureAvailable(Android.Graphics.SurfaceTexture surface, int w, int h)
        {
            Globals g = Globals.getInstance;
            bool flash = g.GetFlash();
            _camera = Android.Hardware.Camera.Open();
            _camera.SetDisplayOrientation(90);
            Android.Hardware.Camera.Parameters param = _camera.GetParameters();
            Android.Hardware.Camera.Size sizePicture = getBestPreviewSize(Resources.DisplayMetrics.WidthPixels, Resources.DisplayMetrics.HeightPixels);
            param.Zoom = 0;
            param.FocusMode = Android.Hardware.Camera.Parameters.FocusModeContinuousPicture;
            param.SetPictureSize(sizePicture.Width, sizePicture.Height);
            param.FlashMode = Android.Hardware.Camera.Parameters.FlashModeOff;
            if (flash)
                param.FlashMode = Android.Hardware.Camera.Parameters.FlashModeOn;
            else
                param.FlashMode = Android.Hardware.Camera.Parameters.FlashModeOff;
            _camera.SetParameters(param);
            try
            {
                _camera.SetPreviewTexture(surface);
                _camera.StartPreview();
            }
            catch (Java.IO.IOException ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        private Android.Hardware.Camera.Size getBestPreviewSize(int width, int height)
        {
            Android.Hardware.Camera.Size result = null;
            Android.Hardware.Camera.Parameters p = _camera.GetParameters();
            IList<Android.Hardware.Camera.Size> Sizes = p.SupportedPictureSizes;
            foreach (Android.Hardware.Camera.Size size in Sizes)
            {
                if (size.Width <= width && size.Height <= height)
                {
                    if (result == null)
                    {
                        result = size;
                    }
                    else
                    {
                        int resultArea = result.Width * result.Height;
                        int newArea = size.Width * size.Height;

                        if (newArea > resultArea)
                        {
                            result = size;
                        }
                    }
                }
            }
            return result;
        }
        public bool OnSurfaceTextureDestroyed(Android.Graphics.SurfaceTexture surface)
        {
            _camera.StopPreview();
            _camera.Release();

            return true;
        }
        public void OnSurfaceTextureSizeChanged(Android.Graphics.SurfaceTexture surface, int width, int height)
        {
            _camera.StopPreview();
            _camera.SetPreviewTexture(surface);
            _camera.StartPreview();
        }
        public void OnSurfaceTextureUpdated(Android.Graphics.SurfaceTexture surface)
        {
        }
        public void OnPictureTaken(byte[] data, Android.Hardware.Camera camera)
        {
            _camera.StopPreview();
            Bitmap picture = BitmapFactory.DecodeByteArray(data, 0, data.Length);
            UserPicture = RotateBitmap(picture,90);
            Globals g = Globals.getInstance;
            g.SetPicture(UserPicture);
            Intent PictureActivity = new Intent(this, typeof(PictureActivity));
            this.StartActivity(PictureActivity);
            _camera.StartPreview();
        }
        public static Bitmap RotateBitmap(Bitmap source, float angle)
        {
            Matrix matrix = new Matrix();
            matrix.PostRotate(angle);
            return Bitmap.CreateBitmap(source, 0, 0, source.Width, source.Height, matrix, true);
        }
    }
}
namespace-CameraStream
{
[活动(Label=“CameraStream”,MainLauncher=true,Icon=“@drawable/SendButton”,Theme=“@android:style/Theme.NoTitleBar”)]
公共类活动1:活动,TextureView.ISurfaceTextureListener,IPictureCallback
{
Android.Hardware.Camera\u-Camera;
纹理视图(TextureView);;
按钮按钮按钮;
切换按钮FlashBtn;
位图用户图片;
创建时受保护的覆盖无效(捆绑包)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
_textureView=FindViewById(Resource.Id.textureView);
_textureView.SurfaceTextureRelistener=此;
TakePictureBtn=FindViewById(Resource.Id.takePhotoButton);
TakePictureBtn.Click+=TakePicture\u Click;
FlashBtn=findviewbyd(Resource.Id.toggleFlashButton);
FlashBtn.CheckedChange+=单击Flash\u;
}
私有无效Flash_单击(对象发送者,CompoundButton.CheckedChangeEventArgs e)
{
Globals g=Globals.getInstance;
Android.Hardware.Camera.Parameters参数=_Camera.GetParameters();
如果(如已检查)
{
g、 SetFlash(真);
FlashBtn.SetBackgroundResource(Resource.Drawable.NoFlashButton);
param.FlashMode=Android.Hardware.Camera.Parameters.FlashModeOn;
_摄像机参数设置(参数);
}
其他的
{
g、 SetFlash(假);
FlashBtn.SetBackgroundResource(Resource.Drawable.FlashButton);
param.FlashMode=Android.Hardware.Camera.Parameters.FlashModeOff;
_摄像机参数设置(参数);
}
}
私有无效拍摄照片\u单击(对象发送者,事件参数e)
{
_拍照(空,空,这个);
}
SurfaceTextureAvailable上的公共空白(Android.Graphics.SurfaceTexture surface,int w,int h)
{
Globals g=Globals.getInstance;
bool flash=g.GetFlash();
_camera=Android.Hardware.camera.Open();
_摄像头。设置显示方向(90);
Android.Hardware.Camera.Parameters参数=_Camera.GetParameters();
Android.Hardware.Camera.Size sizePicture=getBestPreviewSize(Resources.DisplayMetrics.WidthPixels,Resources.DisplayMetrics.HeightPixels);
参数缩放=0;
param.FocusMode=Android.Hardware.Camera.Parameters.FocusModeContinuousPicture;
参数SetPictureSize(sizePicture.Width、sizePicture.Height);
param.FlashMode=Android.Hardware.Camera.Parameters.FlashModeOff;
如果(闪存)
param.FlashMode=Android.Hardware.Camera.Parameters.FlashModeOn;
其他的
param.FlashMode=Android.Hardware.Camera.Parameters.FlashModeOff;
_摄像机参数设置(参数);
尝试
{
_摄像头。设置预览纹理(表面);
_camera.StartPreview();
}
捕获(Java.IO.IOException-ex)
{
控制台写入线(例如消息);
}
}
私有Android.Hardware.Camera.Size getBestPreviewSize(整数宽度,整数高度)
{
Android.Hardware.Camera.Size结果=null;
Android.Hardware.Camera.Parameters p=_Camera.GetParameters();
IList size=p.SupportedPictureSizes;
foreach(Android.Hardware.Camera.Size in Size)
{

如果(size.Width
fitXY
可能会扭曲纵横比,您应该获得可用的相机预览尺寸,并调整TextReview的大小以匹配或使用textview裁剪到实际相机的预览。@Sushingover我已经尝试使用_TextReview.LayoutParameters=new Fr调整纹理视图的大小ameLayout.LayoutParams(w,h);其中w和h是sizePicture.Widt和sizePicture.Height,但它也不起作用。我已将android:scaleType=“fitXY”更改为行android:scaleType=“centerCrop”但这两种方式都不起作用。您应该获得可用的摄像头支持的预览尺寸,并根据设备的分辨率以及在UI中显示TextureView的方式使用其中一种尺寸。还要记住,不同的设备制造商将其摄像头芯片旋转90度,因此您必须处理横向/portait/aspect ratio/…在缩放和/或旋转给定的“预览”时,您自己会考虑到这一点。