See the question and my original answer on StackOverflow

ZXing (ZXing.NET is a port) is completely platform agnostic, so it works fine with any technology as long as you can capture a "bitmap" (RGB, etc.) of some kind whatever that means on a given platform.

Here is WinUI3 (make sure you have the latest WinUI3 nugets installed) sample application that does two things:

  • It captures the (first on your PC) webcam outputs and displays it in a WinUI3 MediaPlayerElement.
  • For each frame, it runs ZXing barcode reader decoding, trying to find a QR Code, and it displays it when it finds one.

The code could be easily changed to read any barcode (EAN13, etc.) that XZing supports. It contains a thin adaptation layer between XZing and WinRT's SoftwareBitmap (that I have copied from XZing.NET code):

Here is the XAML for a WinUI3 page:

        <RowDefinition Height="30" />
        <RowDefinition Height="30" />
        <RowDefinition Height="*" />

    <Button Click="Button_Click">Toggle Capture</Button>
    <TextBox x:Name="textBox" Grid.Row="1" />
        AutoPlay="True" />

And the code in a WinUI3 page (you need the XZing.NET nuget package installed):

public sealed partial class MainPage : Page
    private readonly SoftwareBitmapBarcodeReader _reader;
    private MediaCapture _capture;
    private MediaFrameReader _frameReader;
    private MediaSource _mediaSource;

    public MainPage()

        // set various xzing options (beware, all formats like All_1D can divide perf by orders of magnitude)
        _reader = new SoftwareBitmapBarcodeReader
            AutoRotate = true
        _reader.Options.PossibleFormats = new[] { BarcodeFormat.QR_CODE };
        _reader.Options.TryHarder = true;

    private async void Button_Click(object sender, RoutedEventArgs e)
        if (_capture == null)
            await InitializeCaptureAsync();
        await TerminateCaptureAsync();

    private async Task InitializeCaptureAsync()
        // get first capture device (change this if you want)
        var sourceGroup = (await MediaFrameSourceGroup.FindAllAsync())?.FirstOrDefault();
        if (sourceGroup == null)
            return; // not found!

        // init capture & initialize
        _capture = new MediaCapture();
        await _capture.InitializeAsync(new MediaCaptureInitializationSettings
            SourceGroup = sourceGroup,
            SharingMode = MediaCaptureSharingMode.SharedReadOnly,
            MemoryPreference = MediaCaptureMemoryPreference.Cpu, // to ensure we get SoftwareBitmaps

        // initialize source
        var source = _capture.FrameSources[sourceGroup.SourceInfos[0].Id];

        // create reader to get frames & pass reader to player to visualize the webcam
        _frameReader = await _capture.CreateFrameReaderAsync(source, MediaEncodingSubtypes.Bgra8);
        _frameReader.FrameArrived += OnFrameArrived;
        await _frameReader.StartAsync();

        _mediaSource = MediaSource.CreateFromMediaFrameSource(source);
        player.Source = _mediaSource;

    private void OnFrameArrived(MediaFrameReader sender, MediaFrameArrivedEventArgs args)
        var bmp = sender.TryAcquireLatestFrame()?.VideoMediaFrame?.SoftwareBitmap;
        if (bmp == null)

        var result = _reader.Decode(bmp);
        if (result != null)
            // found a QR CODE
            DispatcherQueue.TryEnqueue(() =>
                textBox.Text = result.BarcodeFormat + ": " + result.Text;

    private async Task TerminateCaptureAsync()
        player.Source = null;

        _mediaSource = null;

        if (_frameReader != null)
            _frameReader.FrameArrived -= OnFrameArrived;
            await _frameReader.StopAsync();
            _frameReader = null;

        _capture = null;

// this is the thin layer that allows you to use XZing over WinRT's SoftwareBitmap
public class SoftwareBitmapBarcodeReader : BarcodeReader<SoftwareBitmap>
    public SoftwareBitmapBarcodeReader()
        : base(bmp => new SoftwareBitmapLuminanceSource(bmp))

// from
public class SoftwareBitmapLuminanceSource : BaseLuminanceSource
    protected SoftwareBitmapLuminanceSource(int width, int height)
      : base(width, height)

    public SoftwareBitmapLuminanceSource(SoftwareBitmap softwareBitmap)
        : base(softwareBitmap.PixelWidth, softwareBitmap.PixelHeight)
        if (softwareBitmap.BitmapPixelFormat != BitmapPixelFormat.Gray8)
            using SoftwareBitmap convertedSoftwareBitmap = SoftwareBitmap.Convert(softwareBitmap, BitmapPixelFormat.Gray8);

    protected override LuminanceSource CreateLuminanceSource(byte[] newLuminances, int width, int height)
        => new SoftwareBitmapLuminanceSource(width, height) { luminances = newLuminances };

And here is the result on a QR Code that encodes "Hello World":

enter image description here