Search code examples
xamarin.formsxamarin.androidbackground-colorpinchzoom

Using pinch to zoomin and zoomout some unwanted background should copied color appeared and pixel quality low android below 9 version Xamarin android


enter image description hereWhenever i using wo fingers pinch to zoomin and zoomout some unwanted background should copied color appeared my camerapagerenderer if i single touch or touch it not seems to be apppear when i pinch to zoomin using two fingers it appears on my screen

    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 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);
                }
                else
                {
                    Android.Util.Log.Error("lv", "zoom not supported");
                }
            }
        private static float getFingerSpacing(MotionEvent e)
            {
         if(e.PointerCount==2)
    {
               int pointerIndex = e.FindPointerIndex(_activePointerId);
                float x = e.GetX(pointerIndex);
                float y = e.GetY(pointerIndex);
        return (float)Math.Sqrt(x * x + y * y);
    }
        }

Solution

  • You could check the code below. It works on Android 10.0 with no color shades.

     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)
        {
            //camera.StopPreview();
            //  camera.Release();
            // camera = global::Android.Hardware.Camera.Open((int)cameraType);
            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();
        }       
    }
    

    Update: The result on Android 6.0

    enter image description here