我正在尝试为我的相机页面实现一个手动对焦功能,这样用户就可以点击来对焦相机。
我在原生Android上使用this StackOverflow question that's currently written in Java,我已经把它转换成C#用于我的Xamarin.Forms Android应用程序。
以下是我目前掌握的情况:
public class CameraPage : PageRenderer, TextureView.ISurfaceTextureListener, Android.Views.View.IOnTouchListener, IAutoFocusCallback
{
global::Android.Hardware.Camera camera;
TextureView textureView;
public void OnAutoFocus(bool success, Android.Hardware.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();
}
}
public bool OnTouch(Android.Views.View v, MotionEvent e)
{
if (camera != null)
{
var parameters = camera.GetParameters();
camera.CancelAutoFocus();
Rect focusRect = CalculateTapArea(e.GetX(), e.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(OnAutoFocus); //Here is the issue. How do I use the callback?
}
catch (System.Exception ex)
{
Console.WriteLine(ex.ToString());
Console.Write(ex.StackTrace);
}
return true;
}
return false;
}
private Rect CalculateTapArea(object x, object y, float coefficient)
{
var focusAreaSize = 500;
int areaSize = Java.Lang.Float.ValueOf(focusAreaSize * coefficient).IntValue();
int left = clamp((int)x - areaSize / 2, 0, textureView.Width - areaSize);
int top = clamp((int)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;
}
}
我已经成功地转换了大部分内容,但我不确定如何正确地使用AutoFocusCallback。我应该怎么做才能像上面链接的java答案那样从我的OnTouch事件调用OnAutoFocus?
附加回调后,我需要做的就是将OnTouch事件订阅到我的页面,对吗?
例如,我尝试过:textureView.Click += OnTouch;
,但"OnTouch“没有与委托”EventHandler“匹配的重载。是否需要使用特定的事件处理程序?
3条答案
按热度按时间knsnq2tg1#
你可以尝试改变
到
并且它将使用OnAutoFocus,因为它是从IAutoFocusCallback实现的。
关于订阅事件的问题,您可以尝试在OnElementChanged中订阅事件,如下所示
顺便说一句,我没有看到在这个代码中使用
TextureView.ISurfaceTextureListener
。jvlzgdj92#
在链接的Java答案中所发生的一切就是他们提供了在操作系统调用回调时运行的代码:
上面没有“调用”回调,只是提供了回调代码来运行。操作系统调用回调。所以在Xamarin中,你需要传入实现
IAutoFocusCallback
接口的类型,所以我认为你应该能够做到这一点,因为CameraPage实现了IAutoFocusCallback
接口:这里的线索是,当你在
camera.AutoFocus
后面输入左括号时,弹出窗口显示你需要传入一个类型IAutoFocusCallback
,这意味着任何实现该接口的类型,所以在本例中是“this”CameraPage。:-)eqfvzcg83#
因为这里没有完整的例子,这是我的例子。
这个解决方案很好用,至少对我来说是这样。相机会持续对焦,直到一个对焦点被点击。然后它会对焦在点击点上,直到你把相机移开。然后它会回到持续对焦模式。