【问题标题】:Why does live camera capture control with Xamarin Forms on iOS freeze?为什么 iOS 上使用 Xamarin Forms 的实时摄像头捕获控制会冻结?
【发布时间】:2023-03-11 20:38:01
【问题描述】:

我从 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);
        }
    }

【问题讨论】:

  • 我有一个内容视图,有两个按钮,点击按钮时我必须拍摄图像并显示为预览,我该怎么做????
  • @SayedAzharuddin 如果这篇文章没有帮助,请发布另一个问题。另请注意上面的btnTakePicture.Clicked +=... 代码。你可以转换byte[]:var strm = new MemoryStream(buffer); var imgsrc = ImageSource.FromStream(strm);

标签: xamarin xamarin.ios xamarin.forms


【解决方案1】:

我遇到了这个问题,结果证明我因为async/awaitTask.Result 的组合而陷入僵局。猜测一下,您使用Task.Wait() 时可能会遇到类似的情况。

两段代码:

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

还有:

var sampleBuffer = await stillImageOutput.CaptureStillImageTaskAsync(videoConnection);

【讨论】:

  • 所以答案是让我的按钮。单击异步方法?
  • 是的,试试类似:btnTakePicture.Clicked += async (s,e) =&gt; { await GetCameraImage(); };
猜你喜欢
  • 2018-09-13
  • 2012-07-21
  • 2012-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-12
相关资源
最近更新 更多