Пользовательский вид камеры не отображаетсяIOS

Программируем под IOS
Ответить
Anonymous
 Пользовательский вид камеры не отображается

Сообщение Anonymous »

Я использовал zxing.maui nuget для сканирования QR -кода, однако он не работает для некоторых небольших QR -кодов. После некоторого копания я обнаружил, что AvcaptureSession с iavcapturemetadataoutputobjectsdelegate работает для этого. Я имею в виду Vinodios/Swiftqrcodescanner для достижения этого. В отладке я вижу представление создается, а захват, однако, пользовательский интерфейс не показывает предварительного просмотра камеры. Я также пытался добавить эту zxing.maui fork, но iavcapturemetadataoutputobjectsdelegate.didoutputmetadataobjects не попадает там даже при [Export ("CaptureOutput: DidOutputMetAdataObjects: FromConnection:")] . Я посмотрел, как они добавляют sublayering VideoPreviewLayer в библиотеке ZXING.MAUI, а также попробовали это здесь (см. MayoutoutSubviews () ниже). Это также не показывает пользовательского интерфейса.
Я делаю что -то не так, очевидно. Не могу выяснить, что. < /P>

Код: Выделить всё

public class QRCodeReaderView : View
{
public static readonly BindableProperty IsScanningProperty = BindableProperty.Create(nameof(IsScanning), typeof(bool), typeof(CameraView), true);

public bool IsScanning
{
get => (bool)GetValue(IsScanningProperty);
set => SetValue(IsScanningProperty, value);
}

public event EventHandler? OnBarcodeDetected;

public void RaiseBarcodeDetected(string barcode)
{
OnBarcodeDetected?.Invoke(this, new BarcodeDetectedEventArgs(barcode));
}
}
< /code>
public partial class QRCodeReaderViewHandler : ViewHandler
{
protected override IosQRCodeReaderView CreatePlatformView()
{
var control = new IosQRCodeReaderView();
return control;
}

private static void MapIsScanning(QRCodeReaderViewHandler handler, QRCodeReaderView qrCodeReaderView)
{

}

private static void MapOnBarcodeDetected(QRCodeReaderViewHandler handler, QRCodeReaderView qrCodeReaderView, object? args)
{
//TODO
}
}

< /code>
Нативный представление < /p>
using System.Diagnostics;
using AVFoundation;
using CoreAnimation;
using CoreFoundation;
using Foundation;
using UIKit;

namespace QRCodeScanner;

public class IosQRCodeReaderView : UIView, IAVCaptureMetadataOutputObjectsDelegate
{
private readonly AVCaptureDevice? _defaultDevice;
private AVCaptureInput? _defaultCaptureInput => _defaultDevice is not null ?  AVCaptureDeviceInput.FromDevice(_defaultDevice) : null;
private readonly AVCaptureMetadataOutput _dataOutput;
private readonly AVCaptureSession _captureSession;
private readonly AVCaptureDevicePosition _devicePosition = AVCaptureDevicePosition.Back;

public event EventHandler? QRCodeDetected;

private readonly AVCaptureVideoPreviewLayer _videoPreviewLayer;

public IosQRCodeReaderView(AVCaptureDevicePosition position = AVCaptureDevicePosition.Back)
{
_defaultDevice = AVCaptureDevice.GetDefaultDevice(AVMediaTypes.Video);
_captureSession =  new AVCaptureSession();
_devicePosition = position;
_dataOutput = new AVCaptureMetadataOutput();
_videoPreviewLayer = new AVCaptureVideoPreviewLayer(_captureSession)
{
VideoGravity = AVLayerVideoGravity.ResizeAspectFill,
CornerRadius = 10.0f,
};
PrepareQRScanner();
StartScanningQRCode();
}

public override void LayoutSubviews()
{
base.LayoutSubviews();
var transform = CATransform3D.MakeRotation(0, 0, 0, 1.0f);
switch (UIDevice.CurrentDevice.Orientation)
{
case UIDeviceOrientation.Portrait:
transform = CATransform3D.MakeRotation(0, 0, 0, 1.0f);
break;
case UIDeviceOrientation.PortraitUpsideDown:
transform = CATransform3D.MakeRotation((nfloat)Math.PI, 0, 0, 1.0f);
break;
case UIDeviceOrientation.LandscapeLeft:
transform = CATransform3D.MakeRotation((nfloat)(-Math.PI / 2), 0, 0, 1.0f);
break;
case UIDeviceOrientation.LandscapeRight:
transform = CATransform3D.MakeRotation((nfloat)Math.PI / 2, 0, 0, 1.0f);
break;
case UIDeviceOrientation.Unknown:
case UIDeviceOrientation.FaceUp:
case UIDeviceOrientation.FaceDown:
default:
break;
}

_videoPreviewLayer.Transform = transform;
_videoPreviewLayer.Frame = Layer.Bounds;
AddMaskToVideoPreviewLayer();
}

private void SetupCaptureSession()
{
if (_captureSession.Running)
{
return;
}
_captureSession.BeginConfiguration();
switch (_devicePosition)
{
case AVCaptureDevicePosition.Front:

//TODO
break;
case AVCaptureDevicePosition.Unspecified:
case AVCaptureDevicePosition.Back:
if (_defaultCaptureInput is not null &&  _captureSession.CanAddInput(_defaultCaptureInput))
{
_captureSession.AddInput(_defaultCaptureInput);
}
break;
default:
Debug.WriteLine("Do nothing");
break;
}

if (_captureSession.CanAddOutput(_dataOutput)  is false)
{
return;
}
_captureSession.AddOutput(_dataOutput);
_dataOutput.MetadataObjectTypes = _dataOutput.AvailableMetadataObjectTypes;
_dataOutput.SetDelegate(this, DispatchQueue.MainQueue);
Debug.WriteLine(_dataOutput.AvailableMetadataObjectTypes);
_captureSession.CommitConfiguration();
}

private void PrepareQRScanner()
{
SetupCaptureSession();
}

private AVCaptureDeviceInput? GetCurrentInput()
{
if (_captureSession.Inputs.FirstOrDefault() is AVCaptureDeviceInput deviceInput)
{
return deviceInput;
}
return null;
}

private void StartScanningQRCode()
{
if (_captureSession.Running)
{
return;
}
//DispatchQueue.GetGlobalQueue(DispatchQualityOfService.Background).DispatchAsync(_captureSession.StartRunning);
MainThread.BeginInvokeOnMainThread(_captureSession.StartRunning);
}

private void AddMaskToVideoPreviewLayer()
{
//TODO: add
}

private int _delayCount = 0;
private const int MaxDelayCount = 15;

[Export("captureOutput:didOutputMetadataObjects:fromConnection:")]
public void DidOutputMetadataObjects(AVCaptureMetadataOutput captureOutput, AVMetadataObject[] metadataObjects, AVCaptureConnection connection)
{
try
{
foreach (var data in metadataObjects)
{
if (_videoPreviewLayer.GetTransformedMetadataObject(data) is not AVMetadataMachineReadableCodeObject transformed)
continue;
if (Bounds.Contains(transformed.Bounds) is false || _videoPreviewLayer.Bounds.Contains(transformed.Bounds) is false)
continue;
_delayCount += 1;
if (_delayCount < MaxDelayCount)
continue;
if (string.IsNullOrEmpty(transformed.StringValue))
continue;
QRCodeDetected?.Invoke(this, new QRCodeEventArgs(transformed.StringValue));
_captureSession.StopRunning();
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.StackTrace);
}
}
}
< /code>
Назначение обработчика < /p>
builder.ConfigureMauiHandlers(handlers =>
{
handlers.AddHandler();

});
< /code>












< /code>
private async Task CheckAndRequestCameraPermission()
{
var status = await Permissions.CheckStatusAsync();
if (status != PermissionStatus.Granted)
{
status = await Permissions.RequestAsync();
if (status != PermissionStatus.Granted)
{
await DisplayAlert("Camera Permission Denied", "This app needs access to the camera to scan QR codes.", "OK");
return; // Or disable the scanning functionality
}
}
}

protected override async void OnAppearing()
{
base.OnAppearing();
await CheckAndRequestCameraPermission();
}
Если кто -либо есть идея, почему это происходит, что было бы большой помощью.

Подробнее здесь: https://stackoverflow.com/questions/794 ... displaying
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»