在iOS上冻结Xamarin Forms的Live Camera Capture控件

时间:2015-11-22 05:26:50

标签: xamarin xamarin.ios xamarin.forms

我从github下载了Xamarin Moments的来源,现在我正在尝试将CameraPage rendererPage转换为ContentView

然后我重构了代码,使其成为ContentView渲染器。大多数实时预览和图像捕获的实际设置来自Moments应用程序,需要/首选进行一些重构。

现场预览显示但是当我按下按钮拍照时,应用程序会毫无例外地冻结,甚至不在Xcode的控制台视图中。

//this is how it's called: 
btnTakePicture.Clicked += (s,e)=> { GetCameraImage().Wait(); };


// this method freezes
public async Task<byte[]> GetCameraImage()
{
    byte[] imageBuffer = null;

    if (captureDeviceInput != null)
    { 
        var videoConnection = stillImageOutput.ConnectionFromMediaType(AVMediaType.Video);
        Console.WriteLine("[HASFIQWRPPOA] This message shows up");

// this is where the app freezes, even though the live preview still moves.
        var sampleBuffer = await stillImageOutput.CaptureStillImageTaskAsync(videoConnection);
        Console.WriteLine("[CLKJFADSFQXW] THIS DOESN'T SHOW UP");

        // var jpegImageAsBytes = AVCaptureStillImageOutput.JpegStillToNSData (sampleBuffer).ToArray ();
        var jpegImageAsNsData = AVCaptureStillImageOutput.JpegStillToNSData(sampleBuffer);
        Console.WriteLine("[ROIAJDGNQWTG]");
        // var image = new UIImage (jpegImageAsNsData);
        // var image2 = new UIImage (image.CGImage, image.CurrentScale, UIImageOrientation.UpMirrored);
        // var data = image2.AsJPEG ().ToArray ();
        imageBuffer = jpegImageAsNsData.ToArray();
        Console.WriteLine("[FIOUJGAIDGUQ] Image buffer: "+imageBuffer.Length);
    } 

    if (imageBuffer != null && imageBuffer.Length > 100)
    {
        using (var ms = new MemoryStream(imageBuffer))
        {
            var uiimg = UIImage.LoadFromData(NSData.FromStream(ms)); 
            this.Add(new UIImageView(uiimg)); 
        }
    }

    return imageBuffer;
}

以下是我设置实时预览的方法

// This method runs fine and the camera preview is started as expected
    public void SetupLiveCameraStream()
    {
        try
        {   
// add a UIView to the renderer
            liveCameraStream = new UIView()
            { 
                Frame = new CGRect(0f, 0f, Element.Width, Element.Height),  
            };   

            this.Add(liveCameraStream);  
// find a camera
            var captureDevice = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video);

            if (captureDevice != null)
            { 
                Console.WriteLine("[ZKSDJGWEHSY] Capture device found"); // not the case on simulator

                captureSession = new AVCaptureSession(); 

                videoPreviewLayer = new AVCaptureVideoPreviewLayer(captureSession)
                {
                    Frame = liveCameraStream.Bounds
                };

                liveCameraStream.Layer.AddSublayer(videoPreviewLayer);

                ConfigureCameraForDevice(captureDevice);

                captureDeviceInput = AVCaptureDeviceInput.FromDevice(captureDevice);

                var dictionary = new NSMutableDictionary();
                dictionary[AVVideo.CodecKey] = new NSNumber((int)AVVideoCodec.JPEG);
                stillImageOutput = new AVCaptureStillImageOutput()
                {
                    OutputSettings = new NSDictionary()
                };

                captureSession.AddInput(captureDeviceInput);
                captureSession.AddOutput(stillImageOutput);
                captureSession.StartRunning();
                Console.WriteLine("[OIGAJGUWRJHWY] Camera session started"); 
            }
            else
            {
                Console.WriteLine("[OASDFUJGOR] Could not find a camera device");
            } 
        }
        catch (Exception x)
        {
            Console.WriteLine("[QWKRIFQEAHJF] ERROR:" + x);
        }
    }

1 个答案:

答案 0 :(得分:1)

我遇到了这个问题,结果发现我因为async / awaitTask.Result的使用而陷入僵局。猜测你可能会遇到类似Task.Wait()的使用情况。

代码的两个部分:

btnTakePicture.Clicked += await (s,e) => { GetCameraImage().Wait(); };

var sampleBuffer = await stillImageOutput.CaptureStillImageTaskAsync(videoConnection);