On Xamarin Forms Custom renderer android camera, While trying to Zoom In and Zoom Out, Color shades are occurs

Viewed 381

In cameraPageRenderer, we handle zoomIn and zoomOut in our application. When we try to ZoomIn and ZoomOut, several color shades shows. Please take a look at this output image as well as the ZoomIn and ZoomOut codes handled in renderer.

enter image description here

Any Suggestions?

My CameraPage renderer code snippet :

 public class PhotoCameraPageRenderer : PageRenderer, TextureView.ISurfaceTextureListener
 {

    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");
        }
    }

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;
    }
}
1 Answers

The code you provided is not completed. You could check the code below. I tested 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();
    }       
}

enter image description here

Related