如何在 Android xamarin 表单中的 Camerapagerenderer 中实现自动对焦

How to implement AutoFocus in Camerapagerenderer in Android xamarin forms

我在没有实现 AutoFocus 的情况下使用了 CameraPageRenderer。我不知道如何在 Xamarin Android.

中实现它
public async 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();
        }

如果您使用的是相机 API1(旧款),您可以将对焦模式设置为连续,如下所示:

public void OnSurfaceTextureAvailable(SurfaceTexture surface, int width, int height)
{
    try
    {
        var camera = Camera.Open((int)cameraType);
        var parameters = camera.GetParameters();

        //SET FOCUS MODE HERE
        parameters.FocusMode = Camera.Parameters.FocusModeContinuousPicture;

        camera.SetParameters(parameters);
    }
    catch (Exception ex)
    {
        //log error
        return;
    }

    //other code related to the camera
    textureView.LayoutParameters = new FrameLayout.LayoutParams(width, height);
    surfaceTexture = surface;

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

CameraPageRenderer 开始,通过在 CameraPageRenderer 中实现 IAutoFocusCallback,在相机属性中设置“对焦模式”。

  public class CameraPageRenderer : PageRenderer, TextureView.ISurfaceTextureListener, IAutoFocusCallback
{

然后执行OnAutoFocus方法,设置AutoFocus。

 public void OnAutoFocus(bool success, Camera camera)
    {
        var parameters = camera.GetParameters();
        if (parameters.FocusMode != Android.Hardware.Camera.Parameters.FocusModeContinuousPicture)
        {
            parameters.FocusMode = Android.Hardware.Camera.Parameters.FocusModeContinuousPicture;

            if (parameters.MaxNumFocusAreas > 0)
            {
                parameters.FocusAreas = null;
            }
            camera.SetParameters(parameters);
            camera.StartPreview();
        }
    }

更新:

我正在关注此主题 (),为 CameraPageRenderer 添加自动对焦。

  private void TextureView_Touch(object sender, TouchEventArgs e)
    {
        if (camera != null)
        {
            var parameters = camera.GetParameters();
            camera.CancelAutoFocus();
            Rect focusRect = CalculateTapArea(e.Event.GetX(), e.Event.GetY(), 1f);

            if (parameters.FocusMode != Android.Hardware.Camera.Parameters.FocusModeAuto)
            {
                parameters.FocusMode = Android.Hardware.Camera.Parameters.FocusModeAuto;
            }
            if (parameters.MaxNumFocusAreas > 0)
            {
                List<Area> mylist = new List<Area>();
                mylist.Add(new Android.Hardware.Camera.Area(focusRect, 1000));
                parameters.FocusAreas = mylist;
            }

            try
            {
                camera.CancelAutoFocus();
                camera.SetParameters(parameters);
                camera.StartPreview();
                camera.AutoFocus(this);

                MarginLayoutParams margin = new MarginLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WrapContent,
       ViewGroup.LayoutParams.WrapContent));
                margin.SetMargins(focusRect.Left, focusRect.Top,
                    focusRect.Right, focusRect.Bottom);
                FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(margin);
                layoutParams.Height = 200;
                layoutParams.Width = 200;
                takePhotoButton.LayoutParameters = layoutParams;
                takePhotoButton.Visibility = ViewStates.Visible;
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
                Console.Write(ex.StackTrace);
            }
            //return true;
        }
        else
        {
            //return false;
        }
    }
private Rect CalculateTapArea(object x, object y, float coefficient)
    {
        var focusAreaSize = Math.Max(textureView.Width, textureView.Height) / 8; //Recommended focus area size from the manufacture is 1/8 of the image
        int areaSize = focusAreaSize * (int)coefficient;

        int left = clamp(Convert.ToInt32(x) - areaSize / 2, 0, textureView.Width - areaSize);
        int top = clamp(Convert.ToInt32(y) - areaSize / 2, 0, textureView.Height - areaSize);

        RectF rectF = new RectF(left, top, left + areaSize, top + areaSize);
        Matrix.MapRect(rectF);

        return new Rect((int)System.Math.Round(rectF.Left), (int)System.Math.Round(rectF.Top), (int)System.Math.Round(rectF.Right), (int)System.Math.Round(rectF.Bottom));
    }

    private int clamp(int x, int min, int max)
    {
        if (x > max)
        {
            return max;
        }
        if (x < min)
        {
            return min;
        }
        return x;
    }

    public void OnAutoFocus(bool success, Camera camera)
    {
        var parameters = camera.GetParameters();
        if (parameters.FocusMode != Android.Hardware.Camera.Parameters.FocusModeContinuousPicture)
        {
            parameters.FocusMode = Android.Hardware.Camera.Parameters.FocusModeContinuousPicture;

            if (parameters.MaxNumFocusAreas > 0)
            {
                parameters.FocusAreas = null;
            }
            camera.SetParameters(parameters);
            camera.StartPreview();
            
        }
        if(success)
        {
            Task.Delay(1000);
            this.takePhotoButton.Visibility = ViewStates.Invisible;
        }
       
    }

更新: