【问题标题】:Xamarin Forms - Take photograph without any user interactionXamarin Forms - 无需任何用户交互即可拍照
【发布时间】:2020-08-26 15:20:15
【问题描述】:

我需要在 Xamarin Forms 中为用户拍照,而无需他们按下快门按钮。例如,当应用启动时,它应该显示预览并从 5 秒开始倒计时(让用户有机会就位),然后自动拍照。

我尝试过Xamarin Media Plugin library,但this stackoverflow postthis GitHub issue 声明此功能不受支持。

我看到了一些死讨论,例如this,人们问类似的问题没有解决办法。

我尝试了LeadTools AutoCapture 示例,但这似乎只适用于文档/文本而不是人(除非我遗漏了什么??)。

我现在正在研究 Camera2Basic 示例,该示例已经很老了,并且仅通过 android.hardware.camera2 以 Android 为目标。

是否有任何示例(或第 3 方库)可以满足此要求?理想情况下,我希望它是跨平台的(iOS 和 Android),但目前主要关注的是 Android。

【问题讨论】:

标签: android xamarin.forms


【解决方案1】:

您可以创建 Custom View Renderer on Android 来实现这一点。

基于this offical sample更方便,只需修改如下代码即可实现。

这个官方示例可以在 Xamarin Forms App 中预览相机视图,我们只需要添加一个Timer 以在 5 秒后从相机调用 Frame。修改后的 Renderer 代码如下:

public class CameraPreviewRenderer : ViewRenderer<CustomRenderer.CameraPreview, CustomRenderer.Droid.CameraPreview>, Camera.IPreviewCallback
{
    CameraPreview cameraPreview;
    byte[] tmpData;
    public CameraPreviewRenderer(Context context) : base(context)
    {
    }

    protected override void OnElementChanged(ElementChangedEventArgs<CustomRenderer.CameraPreview> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement != null)
        {
            // Unsubscribe
            cameraPreview.Click -= OnCameraPreviewClicked;
        }
        if (e.NewElement != null)
        {
            if (Control == null)
            {
                cameraPreview = new CameraPreview(Context);
                SetNativeControl(cameraPreview);
            }
            Control.Preview = Camera.Open((int)e.NewElement.Camera);

            // Subscribe
            cameraPreview.Click += OnCameraPreviewClicked;

           
        }
    }

    protected override void OnAttachedToWindow()
    {
        base.OnAttachedToWindow();

        // call the timer method to get the current frame.
        Device.StartTimer(new TimeSpan(0, 0, 5), () =>
        {
            // do something every 5 seconds
            Device.BeginInvokeOnMainThread(() =>
            {
                Console.WriteLine("get data"+tmpData);
                // using MessagingCenter to pass data to forms
                MessagingCenter.Send<object, byte[]>(this, "CameraData", tmpData);

                cameraPreview.Preview.StopPreview();
                cameraPreview.IsPreviewing = false;
                // interact with UI elements
            });

            return false; // runs again, or false to stop
        });
    }

    void OnCameraPreviewClicked(object sender, EventArgs e)
    {
        if (cameraPreview.IsPreviewing)
        {
            cameraPreview.Preview.StopPreview();
            cameraPreview.IsPreviewing = false;
        }
        else
        {
            cameraPreview.Preview.SetPreviewCallback(this);
            cameraPreview.Preview.StartPreview();
            cameraPreview.IsPreviewing = true;
            
        }
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            Control.Preview.Release();
        }
        base.Dispose(disposing);
    }

    // get frame all the time
    public void OnPreviewFrame(byte[] data, Camera camera)
    {
        tmpData = data;
    }
}

现在,Xamarin Forms 可以接收来自MessagingCenter 的数据:

MessagingCenter.Subscribe<object, byte[]>(this, "CameraData", async (sender, arg) =>
{
    MemoryStream stream = new MemoryStream(arg);
    if (stream != null)
    {
        //image is defined in Xaml
        image.Source = ImageSource.FromStream(() => stream);
    }
});

imageXAML 中定义:&lt;Image x:Name="image" WidthRequest="200" HeightRequest="200"/&gt;

【讨论】:

  • 您提到的示例至少现在使用Camera2,而您的代码使用Camera,已弃用。我想这行不通?如何从Camera2 获取预览数据?
猜你喜欢
  • 2012-04-02
  • 1970-01-01
  • 1970-01-01
  • 2021-11-17
  • 2014-11-03
  • 2017-11-04
  • 2016-10-17
  • 1970-01-01
  • 2016-11-22
相关资源
最近更新 更多