newxamarin
newxamarin

Reputation: 89

How to do when taking before picture zoomin and zoomout Camerrenderer Android xamarin forms

enter image description herenow am implementing zoomin and zoomout when before taking picture its not working properly, But its not working properly? Is there any example? I call that function when device recognize pinch gesture. Thank you in advance.

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;

        }

Upvotes: 0

Views: 342

Answers (1)

Jessie Zhang -MSFT
Jessie Zhang -MSFT

Reputation: 13909

Here is related code about the function, please check it.

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

Refer: https://learn.microsoft.com/en-us/answers/questions/343552/zoom-in-camera2basic-xamarin.html

Update:

If you use it in xamarin form, you can refer to the following code:

[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 & 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 && 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();
        }

    }
}

Upvotes: 1

Related Questions