Как это делается при съемке перед тем, как увеличить и уменьшить масштаб камеры в формах Android xamarin

#xamarin.android #zooming #pinchzoom

Вопрос:

введите описание изображения здесьтеперь я применяю масштабирование и уменьшение масштаба, когда перед съемкой он не работает должным образом, но он не работает должным образом? Есть ли какой-нибудь пример? Я вызываю эту функцию, когда устройство распознает жест щипка. Заранее спасибо.

 public override bool OnTouchEvent(MotionEvent e)
        {
            global::Android.Hardware.Camera.Parameters parameters = camera.GetParameters();
            maximumZoomLevel = (float)cameraCharacteristics?.Get(CameraCharacteristics.ScalerAvailableMaxDigitalZoom);
            Android.Graphics.Rect rect = (Android.Graphics.Rect)cameraCharacteristics?.Get(CameraCharacteristics.SensorInfoActiveArraySize);
            if (rect == null) return false;
            float currentFingerSpacing;
            if (e.PointerCount == 2)
            {
                currentFingerSpacing = getFingerSpacing(e);
                float delta = 0.05f;
                if (fingerSpacing != 0)
                {
                    if (currentFingerSpacing > fingerSpacing)
                    { //Don't over zoom-in
                        if ((maximumZoomLevel - zoomLevel) <= delta)
                        {
                            delta = maximumZoomLevel - zoomLevel;
                        }
                        zoomLevel = zoomLevel   delta;
                    }
                    else if (currentFingerSpacing < fingerSpacing)
                    { //Don't over zoom-out
                        if ((zoomLevel - delta) < 1f)
                        {
                            delta = zoomLevel - 1f;
                        }
                        zoomLevel = zoomLevel - delta;
                    }
                    float ratio = (float)1 / zoomLevel; 
                                                       
                    int croppedWidth = (int)(rect.Width() - Math.Round((float)rect.Width() * ratio));
                    int croppedHeight = (int)(rect.Height() - Math.Round((float)rect.Height() * ratio));
                    //Finally, zoom represents the zoomed visible area
                    zoom = new Android.Graphics.Rect(croppedWidth / 2, croppedHeight / 2,
                            rect.Width() - croppedWidth / 2, rect.Height() - croppedHeight / 2);
                    previewRequestBuilder.Set(CaptureRequest.ScalerCropRegion, zoom);
                }
                fingerSpacing = currentFingerSpacing;
                captureSession.SetRepeatingRequest(previewRequestBuilder.Build(), CaptureCallBack, null);

            }
            return true;

        }
 

Комментарии:

1. Характеристика камеры возвращает значение null, я не знаю, почему это происходит

2. частное статическое пространство с плавающей точкой getFingerSpacing(событие движения e) { float x = e.getX(0) — e.getX(1); float y = e.getY(0) — e.getY(1); возврат (float)Math.Sqrt(x * x y * y); } он всегда возвращает исключение индекса указателя

Ответ №1:

Вот соответствующий код функции, пожалуйста, проверьте его.

 var manager = Android.App.Application.Context.GetSystemService(Context.CameraService) as CameraManager;
var id_list = manager.GetCameraIdList();
var characteristics = manager.GetCameraCharacteristics(id_list[0]);
float maxZoom;
Rect mSensorSize = (Rect)characteristics.Get(CameraCharacteristics.SensorInfoActiveArraySize);
if (mSensorSize == null)
{
    maxZoom = 1.0f;
    return;
}
Rect mCropRegion = new Rect();
float zoom = 1.5f;
var newZoom = MathUtils.Clamp(zoom, 1.0f, 6.0f);
int centerX = mSensorSize.Width() / 2;
int centerY = mSensorSize.Height() / 2;
int deltaX = (int)((0.5f * mSensorSize.Width()) / newZoom);
int deltaY = (int)((0.5f * mSensorSize.Height()) / newZoom);
mCropRegion.Set(centerX - deltaX,
        centerY - deltaY,
        centerX   deltaX,
        centerY   deltaY);
mPreviewRequestBuilder.Set(CaptureRequest.ScalerCropRegion, mCropRegion);
mCaptureSession.SetRepeatingRequest(mPreviewRequestBuilder.Build(), null, null);//you could define the callback and handler
 

Обратитесь: https://docs.microsoft.com/en-us/answers/questions/343552/zoom-in-camera2basic-xamarin.html

Обновить:

Если вы используете его в форме xamarin, вы можете обратиться к следующему коду:

 [assembly: ExportRenderer(typeof(CameraPage), typeof(CameraPageRenderer))]
namespace App10.Droid
{
    class CameraPageRenderer : PageRenderer, TextureView.ISurfaceTextureListener
    {
        global::Android.Hardware.Camera camera;
        global::Android.Widget.Button takePhotoButton;
        global::Android.Widget.Button toggleFlashButton;
        global::Android.Widget.Button switchCameraButton;
        global::Android.Views.View view;

        Activity activity;
        CameraFacing cameraType;
        TextureView textureView;
        SurfaceTexture surfaceTexture;

        bool flashOn;

        public CameraPageRenderer(Context context) : base(context)
        {
        }

        float oldDist = 1f;
        public override bool OnTouchEvent(MotionEvent e)
        {

            switch (e.Action amp; MotionEventActions.Mask)
            {
                case MotionEventActions.Down:
                    oldDist = getFingerSpacing(e);
                    break;
                case MotionEventActions.Move:
                    float newDist = getFingerSpacing(e);
                    if (newDist > oldDist)
                    {
                        //mCamera is your Camera which used to take picture, it should already exit in your custom Camera
                        handleZoom(true, camera);
                    }
                    else if (newDist < oldDist)
                    {
                        handleZoom(false, camera);
                    }
                    oldDist = newDist;
                    break;
            }
            return true;
        }
        private static float getFingerSpacing(MotionEvent e)
        {
            if (e.PointerCount == 2)
            {
                float x = e.GetX(0) - e.GetX(1);
                float y = e.GetY(0) - e.GetY(1);
                return (float)Math.Sqrt(x*x   y*y);
            }

            return 0;
        }

        private void handleZoom(bool isZoomIn, global::Android.Hardware.Camera camera)
        {
            global::Android.Hardware.Camera.Parameters parameters = camera.GetParameters();
            if (parameters.IsZoomSupported)
            {
                int maxZoom = parameters.MaxZoom;
                int zoom = parameters.Zoom;

                if (isZoomIn amp;amp; zoom < maxZoom)
                {
                    zoom  ;
                }
                else if (zoom > 0)
                {
                    zoom--;
                }
                parameters.Zoom = zoom;
                camera.SetParameters(parameters);
                camera.SetPreviewTexture(surfaceTexture);
                PrepareAndStartCamera();
            }
            else
            {
                Android.Util.Log.Error("lv", "zoom not supported");
            }
        }


        protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
        {
            base.OnElementChanged(e);
            if (e.OldElement != null || Element == null)
            {
                return;
            }

            try
            {
                SetupUserInterface();
                //SetupEventHandlers();
                AddView(view);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(@"           ERROR: ", ex.Message);
            }
        }

        void SetupUserInterface()
        {
            activity = this.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;
        }

        protected override void OnLayout(bool changed, int l, int t, int r, int b)
        {
            base.OnLayout(changed, l, t, r, b);
            var msw = MeasureSpec.MakeMeasureSpec(r - l, MeasureSpecMode.Exactly);
            var msh = MeasureSpec.MakeMeasureSpec(b - t, MeasureSpecMode.Exactly);

            view.Measure(msw, msh);
            view.Layout(0, 0, r - l, b - t);
        }

        public void OnSurfaceTextureAvailable(SurfaceTexture surface, int width, int height)
        {
            camera = global::Android.Hardware.Camera.Open((int)cameraType);
            textureView.LayoutParameters = new FrameLayout.LayoutParams(width, height);
            surfaceTexture = surface;

            camera.SetPreviewTexture(surface);
            PrepareAndStartCamera();
        }

        public bool OnSurfaceTextureDestroyed(SurfaceTexture surface)
        {
            camera.StopPreview();
            camera.Release();
            return true;
        }

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

        public void OnSurfaceTextureUpdated(SurfaceTexture surface)
        {

        }

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

    }
}
 

Комментарии:

1. как установить mPreviewRequestBuilder и mCaptureSession, потому что это вызывает исключение nullreference

2. я не знаю, почему это происходит, он всегда выдает нулевые значения в mPreviewRequestBuilder, mCaptureSession все, что я пропустил, пожалуйста, дайте мне знать, если я что-то пропустил

3. над скриншотом добавлено

4. пожалуйста, ответьте на эти вопросы. Спасибо

5. как добиться отображения процентного значения масштабирования в визуализаторе (например: значение масштабирования после отображения zoomin 1.0 в пользовательском интерфейсе)