【问题标题】:How can I correctly create my own function to take a photo in Xamarin forms after 10 seconds?如何正确创建自己的功能以在 10 秒后以 Xamarin 形式拍照?
【发布时间】:2016-11-30 06:44:33
【问题描述】:

我正在关注这个项目 https://github.com/ThatCSharpGuy/Forms-FullCameraPage 以实现 xamarin 形式的相机。它可以正常工作,但我想创建自己的空白来拍照。我在该项目中对当前项目的唯一更改是我将 CameraPage 设置为 Contentpage XAML 而不是类。

我们的想法是创建一个函数,以便在 10 秒内拍摄照片,如果可能的话,我想在我的共享代码中控制它。

如果我们查看我添加的代码,这就是我目前得到的。

public CameraPage()
{
        InitializeComponent();
        loadCameraFunction (); //so this is the function that i created myself
}

//i added this and put the same value into them as the ones in `SetPhotoResult`
byte[] image;
int width = -1;
int height = -1;

//the void
async void loadCameraFunction()
{
   await Task.Delay (10000); //wait 10 sec for the photo to be taken
   SetPhotoResult(image, width, height); //i add the byte[] and two ints i created above that has the same value as the ones in SetPhotoResult
}

    public delegate void PhotoResultEventHandler(PhotoResultEventArgs result);

    public event PhotoResultEventHandler OnPhotoResult;


    public void SetPhotoResult(byte[] image, int width = -1, int height = -1)
    {
        OnPhotoResult?.Invoke(new PhotoResultEventArgs(image, width, height));
    }

    public void Cancel()
    {
        OnPhotoResult?.Invoke(new PhotoResultEventArgs());
    }

    public class PhotoResultEventArgs : EventArgs
    {

        public PhotoResultEventArgs()
        {
            Success = false;
        }

        public PhotoResultEventArgs(byte[] image, int width, int height)
        {
            Success = true;
            Image = image;
            Width = width;
            Height = height;
        }

        public byte[] Image { get; private set; }
        public int Width { get; private set; }
        public int Height { get; private set; }
        public bool Success { get; private set; }
    }

}

}

这段代码的问题是我的函数的结果似乎为空。好像我没有得到图像。所以我的问题是:我需要调用SetPhotoResult 函数才能拍照吗?如果是这样,我做错了什么?

【问题讨论】:

    标签: c# xamarin xamarin.forms


    【解决方案1】:

    拍摄照片后应调用SetPhotoResult。如果您只想在点击FullCameraqPagePage 上的“拍照”按钮 10 秒后拍摄一张照片,那么您将需要修改自定义渲染器中的代码。对于 CameraPageRenderer 类中的 iOS,将以下内容添加到 ViewDidLoad 方法的末尾:

    await Task.Delay(10000);
    var data = await CapturePhoto();
    UIImage imageInfo = new UIImage(data);
    
    (Element as FullCameraPage.CameraPage).SetPhotoResult(
            data.ToArray(),
            (int)imageInfo.Size.Width,
            (int)imageInfo.Size.Height);
    

    这与单击 CameraPage 上的圆形按钮时运行的代码相同,但添加了延迟。

    删除取消(左上角的 x)和实际拍照的圆形按钮(第一页上的“拍照”按钮仅加载相机页面,它不拍照)。要删除这些按钮,以便用户不能中断您的图片(好吧,如果他们关闭应用程序,他们仍然可以)然后从CameraPageRendererSetupUserInterface 方法中删除这两行代码:

    View.Add(takePhotoButton);
    View.Add(cancelPhotoButton);
    

    当然,您也可以删除与这两个按钮相关的所有代码。

    对于 Android,同样的想法应该适用。只需将以下内容添加到Android CameraPageRenderer 类中的OnElementChanged 方法中:

    await Task.Delay(5000);
            var bytes = await TakePhoto();
            (Element as CameraPage).SetPhotoResult(bytes, liveView.Bitmap.Width, liveView.Bitmap.Height);
    

    要摆脱手动拍照按钮,请从 SetupUserInterface 方法中删除以下内容:

    mainLayout.AddView(capturePhotoButton);
    

    编辑:在共享代码中完成所有操作:

    将类属性添加到CameraPage,类型为Action

    public Action TakePicture { get; set; }
    

    在CameraPageRenderer中设置Action的代码:

    (安卓):

    (Element as CameraPage).TakePicture = async () =>
    {
         var bytes = await TakePhoto();
        (Element as CameraPage).SetPhotoResult(bytes, liveView.Bitmap.Width, liveView.Bitmap.Height);
    };
    

    (iOS):

    (Element as CameraPage).TakePicture = async () =>
    {
        var data = await CapturePhoto();
        UIImage imageInfo = new UIImage(data);
    
        (Element as FullCameraPage.CameraPage).SetPhotoResult(data.ToArray(),
            (int)imageInfo.Size.Width,
            (int)imageInfo.Size.Height);
    };
    

    然后在CameraPage 再次:

    protected override async void OnAppearing()
    {
        base.OnAppearing();
        if (TakePicture != null)
        {
               await Task.Delay(5000);
               TakePicture();
        }
    }
    

    应该这样做。

    【讨论】:

    • 是的,我可以这样做,但我想在我的共享代码中控制它。这样做的原因是因为我想稍后让它更先进,所以这是一个必须具备的。 photoclick 事件是CapturePhoto 对吗?我可以通过依赖项或前端类似的东西以某种方式到达它吗?
    • 是的,iOS 页面渲染器中的这一行实际上获取了照片的数据:var data = await CapturePhoto();,但您仍然需要调用以下两行才能将照片包获取到原始页面。跨度>
    • 那么我怎样才能在我的原始页面上达到那个确切的功能呢?我习惯于使用依赖服务和接口,这样我可以轻松地运行CapturePhoto 函数,但在渲染器中我不知道如何使它成为可能。我想通过内容页面中的空白来实现,
    • 如果您需要从共享代码中控制的只是延迟时间,您可以将类级别属性添加到 CameraPage 用于延迟时间,然后将其用于自定义渲染器中的延迟await Task.Delay((Element as FullCameraPage.CameraPage).Delay);
    • 就我而言,我不想在渲染器中等待它,因为我想稍后添加更多功能。所以我需要的是达到“照片拍摄事件点击”并在我的内容页面上的空白处使用它。但也许这很难实现。
    猜你喜欢
    • 1970-01-01
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多