フッターコンテンツにスキップ
ビデオ

Migrating from BarcodeScanning.Native.Maui to IronBarcode

BarcodeScanning.Native.MauiからIronBarcodeへの移行

このガイドでは、BarcodeScanning.Native.Maui からIronBarcodeへの完全な移行パスを提供します。カメライベントパターンの置き換え、名前空間の変更、コード移行の例、および BarcodeScanning.Native.Maui では対応できないシナリオ (Windows MAUI、ファイルおよび PDF 入力、サーバー側処理、バーコード生成) の処理について解説します。

BarcodeScanning.MAUIから移行する理由

BarcodeScanning.Native.Mauiから移行したチームは、以下のトリガーを報告しています。

Windows MAUIターゲットが必要です: BarcodeScanning.Native.MauiはiOSおよびAndroidのネイティブAPIをラップします。Windows版は提供されておらず、今後も提供予定はありません。 MAUIアプリがiOSとAndroidに加えてWindowsも対象とする場合、プラットフォーム固有の分岐なしに3つのターゲットすべてで動作するライブラリが必要です。

ファイルまたはPDF入力が要件に追加されました: BarcodeScanning.Native.Mauiはライブカメラフレームのみを受け付けます。 ユーザーがギャラリーから画像をアップロードする必要がある場合、またはサーバー側のエンドポイントがPDFからバーコードを抽出する必要がある場合、このライブラリにはコードパスが提供されていません。 ファイルやPDFのバーコードを扱う場合、それぞれ異なるツールが必要になります。

iOSのUPC-Aデータに製造上の誤りがあった: AppleのVisionフレームワークは、UPC-Aバーコード(EAN-13エンコーディング)に対して13桁の数字を返す。 BarcodeScanning.Native.Maui はこれを修正せずにそのまま渡します。 UPC-Aコードが先頭にゼロを付けて保存されていた場合、在庫記録、POSシステムでの検索、またはサプライチェーンの統合が、気づかないうちに機能不全に陥っていた可能性があります。 IronBarcodeは、手動による正規化を行わずに、正しい12桁のUPC-A値を返します。

PDF417のスキャンは信頼性に欠ける:図書館自身のGitHubの課題報告によると、PDF417は"非常に問題が多く、ほとんどのスキャンが実行されない"とのことだ。配送ラベル、運転免許証、搭乗券などのスキャンにおいては、これは直接的な障害となる。

生成が必要でした: BarcodeScanning.Native.Maui はバーコードを生成できません。 IronBarcodeは、Code128、QRコード、DataMatrixなどの形式のデータを画像ファイルまたはバイト配列として生成します。

サーバーサイド処理の導入: BarcodeScanning.Native.MauiはカメラUIコントロールであり、サーバープロセスでは実行できません。 サーバー側でのバーコード読み取りとモバイルスキャンが同時に必要な場合、 IronBarcodeは同じパッケージとAPIで両方の側面に対応します。

基本的な問題

BarcodeScanning.Native.Mauiは、バーコード読み取りをライブカメラのイベントモデルに完全に依存させます。 要件がそのモデルから外れた瞬間、ライブラリは何も提供しない。

private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
    var barcode = e.BarcodeResults.FirstOrDefault();
    if (barcode != null)
        ResultLabel.Text = barcode.DisplayValue;
}
private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
    var barcode = e.BarcodeResults.FirstOrDefault();
    if (barcode != null)
        ResultLabel.Text = barcode.DisplayValue;
}
Private Sub OnBarcodeDetected(sender As Object, e As OnDetectionFinishedEventArg)
    Dim barcode = e.BarcodeResults.FirstOrDefault()
    If barcode IsNot Nothing Then
        ResultLabel.Text = barcode.DisplayValue
    End If
End Sub
$vbLabelText   $csharpLabel

IronBarcodeは、カメラで撮影した画像、ファイル、PDF、バイト配列など、あらゆるデータ入力を受け付け、あらゆるプラットフォームで動作します。

using IronBarCode;

private async void ScanBarcodeButton_Clicked(object sender, EventArgs e)
{
    var photo = await MediaPicker.CapturePhotoAsync();
    if (photo == null) return;

    using var stream = await photo.OpenReadAsync();
    using var ms = new MemoryStream();
    await stream.CopyToAsync(ms);

    var results = BarcodeReader.Read(ms.ToArray());
    ResultLabel.Text = results.FirstOrDefault()?.Value ?? "No barcode found";
}
using IronBarCode;

private async void ScanBarcodeButton_Clicked(object sender, EventArgs e)
{
    var photo = await MediaPicker.CapturePhotoAsync();
    if (photo == null) return;

    using var stream = await photo.OpenReadAsync();
    using var ms = new MemoryStream();
    await stream.CopyToAsync(ms);

    var results = BarcodeReader.Read(ms.ToArray());
    ResultLabel.Text = results.FirstOrDefault()?.Value ?? "No barcode found";
}
Imports IronBarCode

Private Async Sub ScanBarcodeButton_Clicked(sender As Object, e As EventArgs)
    Dim photo = Await MediaPicker.CapturePhotoAsync()
    If photo Is Nothing Then Return

    Using stream = Await photo.OpenReadAsync()
        Using ms As New MemoryStream()
            Await stream.CopyToAsync(ms)

            Dim results = BarcodeReader.Read(ms.ToArray())
            ResultLabel.Text = If(results.FirstOrDefault()?.Value, "No barcode found")
        End Using
    End Using
End Sub
$vbLabelText   $csharpLabel

IronBarcodeとBarcodeScanning.MAUI:機能比較

フィーチャー BarcodeScanning.MAUI IronBarcode
ライブカメラのフレーム読み取り はい — CameraView コントロール いいえ(MediaPickerを使用してキャプチャし、その後読み取ってください)
アプリ内カメラビューファインダー はい、リアルタイムで連続的に いいえ — MediaPicker を介してシステムカメラ UI を使用します
画像ファイルから読み込む なし はい — BarcodeReader.Read(path)
バイト配列から読み込む なし はい — BarcodeReader.Read(bytes)
ストリームから読み込む なし はい — BarcodeReader.Read(stream)
PDFから読み込む なし はい — BarcodeReader.Read(pdf)
バーコード生成 なし はい — BarcodeWriter + QRCodeWriter
Windows MAUIのサポート なし はい
iOS MAUIのサポート はい はい
Android MAUIのサポート はい はい
macOS MAUIのサポート 記録なし はい
サーバーサイド / ASP.NET なし はい
Docker/Azure/AWSラムダ なし はい
iOS UPC-Aの精度 13桁の数字を返す(バグ)、手動での正規化が必要 正しい12桁のUPC-Aコードを返します
PDF417の信頼性 "ほとんどのスキャンは実行されない"(GitHubの課題) サポート対象
複数バーコード検出 はい (e.BarcodeResults 経由でフレームごとに複数) はい (ExpectMultipleBarcodes オプション)
読書速度制御 None ReadingSpeed.Faster / Balanced / Detailed / ExtremeDetail
ライセンス MIT(オープンソース、無料) 商用プラン —Lite749ドル、Plus1,499ドル、Professional2,999ドル、無制限 5,999ドル
.NET Frameworkのサポート いいえ(マウイ島のみ) はい — .NET Framework 4.6.2以降

クイックスタート:BarcodeScanning.MAUIからIronBarcodeへの移行

ステップ 1: NuGet パッケージを置き換える

BarcodeScanning.Native.Maui を削除します:

dotnet remove package BarcodeScanning.Native.Maui
dotnet remove package BarcodeScanning.Native.Maui
SHELL

IronBarcodeをインストールしてください:

dotnet add package IronBarcode
dotnet add package IronBarcode
SHELL

ステップ 2: 名前空間の更新

すべてのファイルからBarcodeScanning名前空間を削除してください。

// Remove
using BarcodeScanning;
// Remove
using BarcodeScanning;
Imports BarcodeScanning
$vbLabelText   $csharpLabel

IronBarcode名前空間を追加します。

// Add
using IronBarCode;
// Add
using IronBarCode;
Imports IronBarCode
$vbLabelText   $csharpLabel

XAML ファイルでは、scanner: XML 名前空間宣言を削除してください:


xmlns:scanner="clr-namespace:BarcodeScanning;assembly=BarcodeScanning.Native.Maui"

xmlns:scanner="clr-namespace:BarcodeScanning;assembly=BarcodeScanning.Native.Maui"
XML

ステップ 3: ライセンスの初期化

ライセンスの初期化をアプリケーション起動時に追加してください — App.xaml.csにて:

IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
Imports IronBarCode

IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

コード移行の例

カメラスキャン:CameraViewからMediaPickerへ

CameraView コントロールは、連続フレーム検出を使用したリアルタイムのファインダーを提供しました。 IronBarcode の代替品では、MAUI のMediaPickerを使用してシステムカメラを開き、写真を撮影し、結果の画像を処理します。

バーコードスキャン。MAUI アプローチ — XAML:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:scanner="clr-namespace:BarcodeScanning;assembly=BarcodeScanning.Native.Maui">
    <StackLayout>
        <scanner:CameraView x:Name="CameraView"
                            OnDetectionFinished="OnBarcodeDetected"
                            CameraEnabled="True"
                            BarcodeFormats="All"
                            VerticalOptions="FillAndExpand" />
        <Label x:Name="ResultLabel" Text="Waiting for scan..." />
    </StackLayout>
</ContentPage>
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:scanner="clr-namespace:BarcodeScanning;assembly=BarcodeScanning.Native.Maui">
    <StackLayout>
        <scanner:CameraView x:Name="CameraView"
                            OnDetectionFinished="OnBarcodeDetected"
                            CameraEnabled="True"
                            BarcodeFormats="All"
                            VerticalOptions="FillAndExpand" />
        <Label x:Name="ResultLabel" Text="Waiting for scan..." />
    </StackLayout>
</ContentPage>
XML

BarcodeScanning.MAUI アプローチ — コードビハインド:

using BarcodeScanning;

private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
    var barcode = e.BarcodeResults.FirstOrDefault();
    if (barcode != null)
        MainThread.BeginInvokeOnMainThread(() =>
            ResultLabel.Text = barcode.DisplayValue);
}
using BarcodeScanning;

private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
    var barcode = e.BarcodeResults.FirstOrDefault();
    if (barcode != null)
        MainThread.BeginInvokeOnMainThread(() =>
            ResultLabel.Text = barcode.DisplayValue);
}
Imports BarcodeScanning

Private Sub OnBarcodeDetected(sender As Object, e As OnDetectionFinishedEventArg)
    Dim barcode = e.BarcodeResults.FirstOrDefault()
    If barcode IsNot Nothing Then
        MainThread.BeginInvokeOnMainThread(Sub()
                                               ResultLabel.Text = barcode.DisplayValue
                                           End Sub)
    End If
End Sub
$vbLabelText   $csharpLabel

IronBarcodeのアプローチ — XAML:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui">
    <StackLayout>
        <Button Text="Scan Barcode" Clicked="ScanButton_Clicked" />
        <Label x:Name="ResultLabel" Text="Tap to scan..." />
    </StackLayout>
</ContentPage>
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui">
    <StackLayout>
        <Button Text="Scan Barcode" Clicked="ScanButton_Clicked" />
        <Label x:Name="ResultLabel" Text="Tap to scan..." />
    </StackLayout>
</ContentPage>
XML

IronBarcodeのアプローチ — コードビハインド:

using IronBarCode;

private async void ScanButton_Clicked(object sender, EventArgs e)
{
    var photo = await MediaPicker.CapturePhotoAsync();
    if (photo == null) return;

    using var stream = await photo.OpenReadAsync();
    using var ms = new MemoryStream();
    await stream.CopyToAsync(ms);

    var results = BarcodeReader.Read(ms.ToArray());
    var first = results.FirstOrDefault();
    ResultLabel.Text = first?.Value ?? "No barcode found";
}
using IronBarCode;

private async void ScanButton_Clicked(object sender, EventArgs e)
{
    var photo = await MediaPicker.CapturePhotoAsync();
    if (photo == null) return;

    using var stream = await photo.OpenReadAsync();
    using var ms = new MemoryStream();
    await stream.CopyToAsync(ms);

    var results = BarcodeReader.Read(ms.ToArray());
    var first = results.FirstOrDefault();
    ResultLabel.Text = first?.Value ?? "No barcode found";
}
Imports IronBarCode
Imports System.IO
Imports System.Linq

Private Async Sub ScanButton_Clicked(sender As Object, e As EventArgs)
    Dim photo = Await MediaPicker.CapturePhotoAsync()
    If photo Is Nothing Then Return

    Using stream = Await photo.OpenReadAsync()
        Using ms As New MemoryStream()
            Await stream.CopyToAsync(ms)

            Dim results = BarcodeReader.Read(ms.ToArray())
            Dim first = results.FirstOrDefault()
            ResultLabel.Text = If(first?.Value, "No barcode found")
        End Using
    End Using
End Sub
$vbLabelText   $csharpLabel

このコードは、iOS、Android、およびWindows MAUI上で、プラットフォーム固有の分岐なしに動作します。 ユーザーエクスペリエンスは、アプリ内のライブビューファインダーからプラットフォームのネイティブカメラ画面へと変化します。これは、ほとんどのビジネスアプリケーションに適しています。 IronBarcode MAUIの取扱説明書には、その他の設定オプションが記載されています。

1回のスキャンで複数のバーコードを処理する

バーコードスキャン。MAUI アプローチ:

private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
    foreach (var barcode in e.BarcodeResults)
    {
        MainThread.BeginInvokeOnMainThread(() =>
            Console.WriteLine($"Found: {barcode.DisplayValue}"));
    }
}
private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
    foreach (var barcode in e.BarcodeResults)
    {
        MainThread.BeginInvokeOnMainThread(() =>
            Console.WriteLine($"Found: {barcode.DisplayValue}"));
    }
}
Private Sub OnBarcodeDetected(sender As Object, e As OnDetectionFinishedEventArg)
    For Each barcode In e.BarcodeResults
        MainThread.BeginInvokeOnMainThread(Sub()
                                               Console.WriteLine($"Found: {barcode.DisplayValue}")
                                           End Sub)
    Next
End Sub
$vbLabelText   $csharpLabel

IronBarcodeのアプローチ:

using IronBarCode;

private async void ScanButton_Clicked(object sender, EventArgs e)
{
    var photo = await MediaPicker.CapturePhotoAsync();
    if (photo == null) return;

    using var stream = await photo.OpenReadAsync();
    using var ms = new MemoryStream();
    await stream.CopyToAsync(ms);

    var options = new BarcodeReaderOptions
    {
        Speed = ReadingSpeed.Balanced,
        ExpectMultipleBarcodes = true
    };

    var results = BarcodeReader.Read(ms.ToArray(), options);
    foreach (var result in results)
        Console.WriteLine($"{result.Format}: {result.Value}");
}
using IronBarCode;

private async void ScanButton_Clicked(object sender, EventArgs e)
{
    var photo = await MediaPicker.CapturePhotoAsync();
    if (photo == null) return;

    using var stream = await photo.OpenReadAsync();
    using var ms = new MemoryStream();
    await stream.CopyToAsync(ms);

    var options = new BarcodeReaderOptions
    {
        Speed = ReadingSpeed.Balanced,
        ExpectMultipleBarcodes = true
    };

    var results = BarcodeReader.Read(ms.ToArray(), options);
    foreach (var result in results)
        Console.WriteLine($"{result.Format}: {result.Value}");
}
Imports IronBarCode
Imports System.IO

Private Async Sub ScanButton_Clicked(sender As Object, e As EventArgs)
    Dim photo = Await MediaPicker.CapturePhotoAsync()
    If photo Is Nothing Then Return

    Using stream = Await photo.OpenReadAsync()
        Using ms As New MemoryStream()
            Await stream.CopyToAsync(ms)

            Dim options As New BarcodeReaderOptions With {
                .Speed = ReadingSpeed.Balanced,
                .ExpectMultipleBarcodes = True
            }

            Dim results = BarcodeReader.Read(ms.ToArray(), options)
            For Each result In results
                Console.WriteLine($"{result.Format}: {result.Value}")
            Next
        End Using
    End Using
End Sub
$vbLabelText   $csharpLabel

ExpectMultipleBarcodes = true は、最初のバーコードを見つけた後のスキャンを続行するようにリーダーに指示します。 このオプションがない場合、呼び出しは最初に一致した時点で返されるため、単一バーコードのシナリオではより高速になります。

iOS UPC-Aの修正:正規化回避策の削除

コードベースにUPC-Aの先頭ゼロ回避策が含まれている場合は、それを完全に削除してください。 IronBarcodeは、手動操作なしで正しい12桁の値を返します。

BarcodeScanning.MAUI アプローチ — 回避策実施済み:

private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
    var barcode = e.BarcodeResults.FirstOrDefault();
    if (barcode == null) return;

    var value = barcode.DisplayValue;

    // Workaround: Apple Vision returns 13 digits for UPC-A
    if (barcode.BarcodeFormat == BarcodeFormats.Upca && value.Length == 13)
        value = value.Substring(1);

    ProcessBarcode(value, barcode.BarcodeFormat.ToString());
}
private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
    var barcode = e.BarcodeResults.FirstOrDefault();
    if (barcode == null) return;

    var value = barcode.DisplayValue;

    // Workaround: Apple Vision returns 13 digits for UPC-A
    if (barcode.BarcodeFormat == BarcodeFormats.Upca && value.Length == 13)
        value = value.Substring(1);

    ProcessBarcode(value, barcode.BarcodeFormat.ToString());
}
Private Sub OnBarcodeDetected(sender As Object, e As OnDetectionFinishedEventArg)
    Dim barcode = e.BarcodeResults.FirstOrDefault()
    If barcode Is Nothing Then Return

    Dim value = barcode.DisplayValue

    ' Workaround: Apple Vision returns 13 digits for UPC-A
    If barcode.BarcodeFormat = BarcodeFormats.Upca AndAlso value.Length = 13 Then
        value = value.Substring(1)
    End If

    ProcessBarcode(value, barcode.BarcodeFormat.ToString())
End Sub
$vbLabelText   $csharpLabel

IronBarcodeのアプローチ ― 回避策は不要です。

using IronBarCode;

private async void ScanButton_Clicked(object sender, EventArgs e)
{
    var photo = await MediaPicker.CapturePhotoAsync();
    if (photo == null) return;

    using var stream = await photo.OpenReadAsync();
    using var ms = new MemoryStream();
    await stream.CopyToAsync(ms);

    var results = BarcodeReader.Read(ms.ToArray());
    var first = results.FirstOrDefault();
    if (first == null) return;

    // result.Value is the correct 12-digit UPC-A — no normalization needed
    ProcessBarcode(first.Value, first.Format.ToString());
}
using IronBarCode;

private async void ScanButton_Clicked(object sender, EventArgs e)
{
    var photo = await MediaPicker.CapturePhotoAsync();
    if (photo == null) return;

    using var stream = await photo.OpenReadAsync();
    using var ms = new MemoryStream();
    await stream.CopyToAsync(ms);

    var results = BarcodeReader.Read(ms.ToArray());
    var first = results.FirstOrDefault();
    if (first == null) return;

    // result.Value is the correct 12-digit UPC-A — no normalization needed
    ProcessBarcode(first.Value, first.Format.ToString());
}
Imports IronBarCode
Imports System.IO
Imports System.Linq
Imports System.Threading.Tasks

Private Async Sub ScanButton_Clicked(sender As Object, e As EventArgs)
    Dim photo = Await MediaPicker.CapturePhotoAsync()
    If photo Is Nothing Then Return

    Using stream = Await photo.OpenReadAsync()
        Using ms As New MemoryStream()
            Await stream.CopyToAsync(ms)

            Dim results = BarcodeReader.Read(ms.ToArray())
            Dim first = results.FirstOrDefault()
            If first Is Nothing Then Return

            ' result.Value is the correct 12-digit UPC-A — no normalization needed
            ProcessBarcode(first.Value, first.Format.ToString())
        End Using
    End Using
End Sub
$vbLabelText   $csharpLabel

移行後、Substring(1)がペアになっている一致をすべて削除してください — そのコードは不要です。

ファイルとPDFのサポートを追加

BarcodeScanning.Native.Mauiには、ファイルまたはPDF入力に相当する機能はありません。 これが移行時に新たに満たされる要件である場合:

バーコードスキャン。MAUI アプローチ:

// なし equivalent exists — BarcodeScanning.Native.Maui cannot read from files or PDFs
// なし equivalent exists — BarcodeScanning.Native.Maui cannot read from files or PDFs
' なし equivalent exists — BarcodeScanning.Native.Maui cannot read from files or PDFs
$vbLabelText   $csharpLabel

IronBarcodeのアプローチ:

using IronBarCode;

// Read from a file the user picked with FilePicker
private async void ReadFileButton_Clicked(object sender, EventArgs e)
{
    var file = await FilePicker.PickAsync(new PickOptions
    {
        PickerTitle = "Select image or PDF"
    });
    if (file == null) return;

    var results = BarcodeReader.Read(file.FullPath);
    foreach (var result in results)
        ResultLabel.Text += $"\n{result.Format}: {result.Value}";
}

// Read barcodes from a PDF directly — no intermediate image step
private void ReadPdfBarcodes()
{
    var results = BarcodeReader.Read("shipment-manifest.pdf");
    foreach (var result in results)
        Console.WriteLine($"{result.Format}: {result.Value}");
}
using IronBarCode;

// Read from a file the user picked with FilePicker
private async void ReadFileButton_Clicked(object sender, EventArgs e)
{
    var file = await FilePicker.PickAsync(new PickOptions
    {
        PickerTitle = "Select image or PDF"
    });
    if (file == null) return;

    var results = BarcodeReader.Read(file.FullPath);
    foreach (var result in results)
        ResultLabel.Text += $"\n{result.Format}: {result.Value}";
}

// Read barcodes from a PDF directly — no intermediate image step
private void ReadPdfBarcodes()
{
    var results = BarcodeReader.Read("shipment-manifest.pdf");
    foreach (var result in results)
        Console.WriteLine($"{result.Format}: {result.Value}");
}
Imports IronBarCode

' Read from a file the user picked with FilePicker
Private Async Sub ReadFileButton_Clicked(sender As Object, e As EventArgs)
    Dim file = Await FilePicker.PickAsync(New PickOptions With {
        .PickerTitle = "Select image or PDF"
    })
    If file Is Nothing Then Return

    Dim results = BarcodeReader.Read(file.FullPath)
    For Each result In results
        ResultLabel.Text &= vbCrLf & $"{result.Format}: {result.Value}"
    Next
End Sub

' Read barcodes from a PDF directly — no intermediate image step
Private Sub ReadPdfBarcodes()
    Dim results = BarcodeReader.Read("shipment-manifest.pdf")
    For Each result In results
        Console.WriteLine($"{result.Format}: {result.Value}")
    Next
End Sub
$vbLabelText   $csharpLabel

IronBarcodeのPDF読み取りに関するドキュメントでは、複数ページのPDFのサポートとページ範囲の選択について説明しています。

サーバー側バーコード処理

アプリケーションにバーコード処理も必要なバックエンドASP.NET APIがある場合、同じBarcodeReader.Read()呼び出しが未変更で実行されます。 BarcodeScanning.Native.Mauiには、サーバー側で同等の機能はありません。

バーコードスキャン。MAUI アプローチ:

// なし equivalent exists — BarcodeScanning.Native.Maui is a camera UI control
// and cannot run in a server process
// なし equivalent exists — BarcodeScanning.Native.Maui is a camera UI control
// and cannot run in a server process
' なし equivalent exists — BarcodeScanning.Native.Maui is a camera UI control
' and cannot run in a server process
$vbLabelText   $csharpLabel

IronBarcodeのアプローチ:

using IronBarCode;

// ASP.NET endpoint — reads barcodes from an uploaded file
[HttpPost("scan")]
public async Task<IActionResult> ScanBarcode(IFormFile file)
{
    using var ms = new MemoryStream();
    await file.CopyToAsync(ms);

    var results = BarcodeReader.Read(ms.ToArray());
    var values = results.Select(r => new { r.Value, Format = r.Format.ToString() });
    return Ok(values);
}
using IronBarCode;

// ASP.NET endpoint — reads barcodes from an uploaded file
[HttpPost("scan")]
public async Task<IActionResult> ScanBarcode(IFormFile file)
{
    using var ms = new MemoryStream();
    await file.CopyToAsync(ms);

    var results = BarcodeReader.Read(ms.ToArray());
    var values = results.Select(r => new { r.Value, Format = r.Format.ToString() });
    return Ok(values);
}
Imports IronBarCode
Imports Microsoft.AspNetCore.Mvc
Imports System.IO
Imports System.Threading.Tasks

' ASP.NET endpoint — reads barcodes from an uploaded file
<HttpPost("scan")>
Public Async Function ScanBarcode(file As IFormFile) As Task(Of IActionResult)
    Using ms As New MemoryStream()
        Await file.CopyToAsync(ms)

        Dim results = BarcodeReader.Read(ms.ToArray())
        Dim values = results.Select(Function(r) New With {Key .Value = r.Value, Key .Format = r.Format.ToString()})
        Return Ok(values)
    End Using
End Function
$vbLabelText   $csharpLabel

モバイルとサーバーの両方で、同じパッケージ、同じAPI、同じ動作。

バーコードの生成

BarcodeScanning.Native.Mauiには生成APIがありません。 IronBarcodeは複数のフォーマットを生成します。

バーコードスキャン。MAUI アプローチ:

// なし equivalent exists — BarcodeScanning.Native.Maui cannot generate barcodes
// なし equivalent exists — BarcodeScanning.Native.Maui cannot generate barcodes
' なし equivalent exists — BarcodeScanning.Native.Maui cannot generate barcodes
$vbLabelText   $csharpLabel

IronBarcodeのアプローチ:

using IronBarCode;

// QR code
QRCodeWriter.CreateQrCode("https://example.com/product/12345", 500)
    .SaveAsPng("qr.png");

// Code128 barcode sized to specific dimensions
BarcodeWriter.CreateBarcode("ITEM-98765", BarcodeEncoding.Code128)
    .ResizeTo(400, 100)
    .SaveAsPng("label.png");

// Get bytes for returning from an API or storing in a database
byte[] barcodeBytes = BarcodeWriter.CreateBarcode("ITEM-98765", BarcodeEncoding.Code128)
    .ToPngBinaryData();
using IronBarCode;

// QR code
QRCodeWriter.CreateQrCode("https://example.com/product/12345", 500)
    .SaveAsPng("qr.png");

// Code128 barcode sized to specific dimensions
BarcodeWriter.CreateBarcode("ITEM-98765", BarcodeEncoding.Code128)
    .ResizeTo(400, 100)
    .SaveAsPng("label.png");

// Get bytes for returning from an API or storing in a database
byte[] barcodeBytes = BarcodeWriter.CreateBarcode("ITEM-98765", BarcodeEncoding.Code128)
    .ToPngBinaryData();
Imports IronBarCode

' QR code
QRCodeWriter.CreateQrCode("https://example.com/product/12345", 500) _
    .SaveAsPng("qr.png")

' Code128 barcode sized to specific dimensions
BarcodeWriter.CreateBarcode("ITEM-98765", BarcodeEncoding.Code128) _
    .ResizeTo(400, 100) _
    .SaveAsPng("label.png")

' Get bytes for returning from an API or storing in a database
Dim barcodeBytes As Byte() = BarcodeWriter.CreateBarcode("ITEM-98765", BarcodeEncoding.Code128) _
    .ToPngBinaryData()
$vbLabelText   $csharpLabel

IronBarcodeの生成に関するドキュメントには、サポートされているすべてのフォーマットとスタイルオプションが記載されています。

BarcodeScanning.MAUI API からIronBarcodeへのマッピングリファレンス

BarcodeScanning.Native.Maui IronBarcode
CameraView XAML コントロール 削除 — Button + MediaPicker.CapturePhotoAsync()を使用
OnDetectionFinished イベント BarcodeReader.Read(imageBytes) 戻り値
OnDetectionFinishedEventArg e BarcodeReader.Read() からの IEnumerable 結果
e.BarcodeResults BarcodeReader.Read() の戻り値
e.BarcodeResults.FirstOrDefault() results.FirstOrDefault()
barcode.DisplayValue result.Value
barcode.BarcodeFormat result.Format
BarcodeFormats="All" 自動検出 - 設定不要
CameraEnabled="True" await MediaPicker.CapturePhotoAsync()
iOSとAndroidのみ iOS、Android、Windows、macOS MAUI
ファイル入力なし BarcodeReader.Read(filePath)
PDF入力なし BarcodeReader.Read("document.pdf")
世代なし BarcodeWriter.CreateBarcode() / QRCodeWriter.CreateQrCode()
iOSのUPC-Aは13桁の数字を返します。 正しい12桁を返します。正規化は不要です。
PDF417は信頼できない サポート対象

一般的な移行の問題と解決策

問題1:ライブビューファインダー体験が失われた

BarcodeScanning.MAUI: CameraView コントロールはMAUIページに直接リアルタイムのカメラプレビューを埋め込みました。 ユーザーはカメラの映像を見ながらバーコードに照準を合わせるだけで、ボタンを押すことなく自動的に検出が行われた。

解決策: MediaPicker.CapturePhotoAsync() は代わりにプラットフォームのカメラスクリーンを表示します。 ほとんどの業務フローにおいては、これは許容範囲内です。 継続的なライブプレビューを必要とするコンシューマーアプリの場合、カメラフレームは直接BarcodeReader.Read()に渡すことができます:

using IronBarCode;

// Continuous scanning: pass camera frame bytes to BarcodeReader.Read()
// (frame capture depends on your MAUI camera frame source)
private void ProcessCameraFrame(byte[] frameBytes)
{
    var results = BarcodeReader.Read(frameBytes);
    if (results.Any())
    {
        var first = results.First();
        MainThread.BeginInvokeOnMainThread(() =>
            ResultLabel.Text = first.Value);
    }
}
using IronBarCode;

// Continuous scanning: pass camera frame bytes to BarcodeReader.Read()
// (frame capture depends on your MAUI camera frame source)
private void ProcessCameraFrame(byte[] frameBytes)
{
    var results = BarcodeReader.Read(frameBytes);
    if (results.Any())
    {
        var first = results.First();
        MainThread.BeginInvokeOnMainThread(() =>
            ResultLabel.Text = first.Value);
    }
}
Imports IronBarCode

' Continuous scanning: pass camera frame bytes to BarcodeReader.Read()
' (frame capture depends on your MAUI camera frame source)
Private Sub ProcessCameraFrame(frameBytes As Byte())
    Dim results = BarcodeReader.Read(frameBytes)
    If results.Any() Then
        Dim first = results.First()
        MainThread.BeginInvokeOnMainThread(Sub()
                                               ResultLabel.Text = first.Value
                                           End Sub)
    End If
End Sub
$vbLabelText   $csharpLabel

これには、カメラのフレームソースをIronBarcodeとは別に配線する必要があります。 この方法を採用する前に、ライブプレビューが本当に必要なのか、それともシステムカメラのユーザーインターフェースで十分なのかを評価してください。

問題2:e.BarcodeResultsプロパティ名と列挙型の変更

BarcodeScanning.MAUI: barcode.DisplayValue はデコードされた文字列を返します; barcode.BarcodeFormat は BarcodeScanning ライブラリの列挙型値を返します。

解決策: DisplayValueresult.Formatに置き換えます。 反復パターンは同じです。

// Before
foreach (var barcode in e.BarcodeResults)
    Console.WriteLine(barcode.DisplayValue);

// After
var results = BarcodeReader.Read(imageBytes);
foreach (var result in results)
    Console.WriteLine(result.Value);
// Before
foreach (var barcode in e.BarcodeResults)
    Console.WriteLine(barcode.DisplayValue);

// After
var results = BarcodeReader.Read(imageBytes);
foreach (var result in results)
    Console.WriteLine(result.Value);
' Before
For Each barcode In e.BarcodeResults
    Console.WriteLine(barcode.DisplayValue)
Next

' After
Dim results = BarcodeReader.Read(imageBytes)
For Each result In results
    Console.WriteLine(result.Value)
Next
$vbLabelText   $csharpLabel

課題3:UI更新のためのスレッドマーシャリング

BarcodeScanning.MAUI: OnDetectionFinished はバックグラウンドスレッドで発火するため、すべてのUI更新はMainThread.BeginInvokeOnMainThread()が必要です。

解決策: MediaPicker + async パターンを使用すると、awaitの後の継続は呼び出しコンテキスト(通常はメインスレッド)に戻ります。 結果表示を囲んでいるMainThread.BeginInvokeOnMainThread()ラッパーは一般的に削除でき、ハンドラーコードを簡素化します。

第4号:MAUIカメラの権限

BarcodeScanning.MAUI: パッケージはInfo.plistに自動的にカメラの権限を追加します。

解決策: IronBarcode でMediaPickerを使用する場合、標準的なMAUIカメラ権限が手動で必要です。 これらはMediaPicker.CapturePhotoAsync()に必要な権限であり、通常はすでに設定されています。 デバイスでテストする前に、android.permission.CAMERANSCameraUsageDescriptionInfo.plistに設定されていることを確認してください。

バーコードスキャン。MAUI移行チェックリスト

マイグレーション前のタスク

変更を加える前に、以下の検索を実行して、BarcodeScanning.Native.Maui の使用状況をすべて確認してください。

grep -rn "using BarcodeScanning" --include="*.cs" .
grep -rn "using BarcodeScanning" --include="*.xaml" .
grep -rn "CameraView" --include="*.cs" .
grep -rn "CameraView" --include="*.xaml" .
grep -rn "OnDetectionFinished" --include="*.cs" .
grep -rn "OnDetectionFinishedEventArg" --include="*.cs" .
grep -rn "e\.BarcodeResults" --include="*.cs" .
grep -rn "DisplayValue" --include="*.cs" .
grep -rn "BarcodeFormats\.Upca" --include="*.cs" .
grep -rn "scanner:" --include="*.xaml" .
grep -rn "using BarcodeScanning" --include="*.cs" .
grep -rn "using BarcodeScanning" --include="*.xaml" .
grep -rn "CameraView" --include="*.cs" .
grep -rn "CameraView" --include="*.xaml" .
grep -rn "OnDetectionFinished" --include="*.cs" .
grep -rn "OnDetectionFinishedEventArg" --include="*.cs" .
grep -rn "e\.BarcodeResults" --include="*.cs" .
grep -rn "DisplayValue" --include="*.cs" .
grep -rn "BarcodeFormats\.Upca" --include="*.cs" .
grep -rn "scanner:" --include="*.xaml" .
SHELL

ヒットごとに記録を残してください。 どのファイルにCameraView XAML 使用が含まれている(XAML の変更が必要)か、対してどのファイルにコードのみの変更が含まれているかを確認してください。 移行後に削除する必要のあるUPC-A正規化の回避策を特定してください。

コード更新タスク

  1. BarcodeScanning.Native.Maui NuGet パッケージを削除
  2. IronBarcode NuGet パッケージをインストール
  3. App.xaml.csに追加
  4. すべてのusing IronBarCode;に置き換える
  5. すべてのXAMLファイルからxmlns:scanner="..."名前空間宣言を削除する
  6. XAML で scanner:CameraView コントロールを Button に置き換え、MediaPicker.CapturePhotoAsync()をトリガーする
  7. XAML からOnDetectionFinished="..." イベント配線を削除する
  8. OnDetectionFinished イベントハンドラーをBarcodeReader.Read()を使用したボタンクリックハンドラーに置き換える
  9. 全体を通してresult.Valueに置き換える
  10. 全体を通してresult.Formatに置き換える
  11. すべてのBarcodeFormats.Upca + Substring(1) 正規化回避策を削除する
  12. 複数のバーコード検出が以前BarcodeReaderOptionsに追加する
  13. 非同期パターンで不要になった場所で、結果表示コードからMainThread.BeginInvokeOnMainThread()ラッパーを削除する
  14. Info.plistカメラ権限が存在することを確認する

移行後のテスト

iOSのバーコードスキャンが正常に動作し、UPC-A値が先頭にゼロのない12桁の文字列として返されることを確認する。

  • Androidバーコードスキャンが、アプリケーションで使用されるすべてのフォーマットで正しい値を生成することを確認する
  • Windowsがビルドターゲットの場合、Windows MAUIのバーコードスキャンが機能することを確認する PDF417スキャンを実際の配送ラベル、運転免許証、搭乗券などと照合してテストしてください(これらの書類を使用する場合)。
  • ExpectMultipleBarcodes = trueで複数のバーコードシナリオをテストし、画像内のすべてのバーコードが返されることを確認する
  • すべてのMAUIターゲットでのファイルピッカースキャン (BarcodeReader.Read(filePath)) が機能することを確認する
  • 移行と同時に追加された新機能である場合は、PDFバーコードの読み取りを確認します。
  • サーバーサイドのBarcodeReader.Read()が、バックエンドコンポーネントが追加された場合に正しい結果を生成することを確認する 既存の自動テストを実行し、バーコード値の出力を移行前の基準値と比較する。

IronBarcodeへの移行の主なメリット

Windows MAUIを完全にサポート: IronBarcodeは、iOS、Android、Windows、macOSという4つのMAUIターゲットすべてで、同じコードとパッケージを使用して動作します。 Windows にはプラットフォーム固有のバーコード実装は不要で、アプリケーションコードに#if WINDOWSブロックは必要ありません。

任意の入力元: BarcodeReader.Read() は、ファイルパス、バイト配列、ストリーム、およびPDFドキュメントを受け入れます。 カメラによるキャプチャ、ファイルアップロード、ギャラリー画像、サーバー側でのPDF処理など、あらゆるバーコード処理シナリオにおいて、同じ結果タイプを持つ同じ静的メソッドが使用されます。

正しいUPC-A値: IronBarcodeは、アプリケーション内に正規化コードがなくても、iOS上で正しい12桁のUPC-A値を返します。 BarcodeScanning.Native.Maui の動作により先頭にゼロが付いた状態で保存された過去の UPC-A データは、移行後に読み取られる値の精度には影響しません。

信頼性の高いPDF417: PDF417は完全にサポートされており、確実に読み込まれます。 配送ラベル、運転免許証、搭乗券は、BarcodeScanning.Native.Maui のGitHub の問題に記載されている"ほとんどのスキャンは発生しない"という制限なしにスキャンできます。

バーコード生成: BarcodeWriter.CreateBarcode() および QRCodeWriter.CreateQrCode() は、Code128、QR、DataMatrix、その他の形式をPNGファイルまたはバイト配列として生成します。 生成と読み込みは、追加の依存関係なしに同じパッケージから利用できます。

サーバーサイドデプロイメント: 同じBarcodeReader.Read()呼び出しがASP.NET、Azure Functions、Dockerコンテナ、およびAWS Lambdaで実行されます。 モバイル端末とサーバーのバーコードロジックは、2つの別々のバーコード実装を維持することなく、同じAPI、同じフォーマットサポート、同じ結果タイプを共有できます。

よくある質問

なぜBarcodeScanning.MAUIからIronBarcodeに移行する必要があるのですか?

一般的な理由としては、ライセンスの簡素化(SDK + ランタイムキーの複雑さの排除)、スループット制限の排除、ネイティブPDFサポートの獲得、Docker/CI/CDデプロイの改善、プロダクションコード内のAPI定型文の削減などが挙げられます。

BarcodeScanning.MAUI APIコールをIronBarcodeに置き換えるには?

インスタンスの作成とライセンスの定型文をIronBarCode.License.LicenseKey = "key "に置き換えてください。リーダー・コールをBarcodeReader.Read(path)に、ライター・コールをBarcodeWriter.CreateBarcode(data, encoding)に置き換えてください。静的メソッドはインスタンス管理を必要としません。

BarcodeScanning.MAUIからIronBarcodeに移行する際、コードはどのくらい変更されますか?

ほとんどのマイグレーションでは、コード行数は少なくなります。ライセンスの定型文、インスタンス・コンストラクタ、明示的なフォーマット設定が削除されます。コアとなる読み取り/書き込み操作は、より短いIronBarcodeに対応し、よりきれいな結果オブジェクトが得られます。

移行時にBarcodeScanning.MAUIとIronBarcodeの両方をインストールしておく必要がありますか?

ほとんどのマイグレーションは、並列操作ではなく、直接置き換えです。一度に1つのサービスクラスを移行し、NuGet参照を置き換え、インスタンス化とAPI呼び出しパターンを更新してから次のクラスに移行します。

IronBarcodeのNuGetパッケージ名は何ですか?

パッケージは'IronBarcode'(大文字のBとC)です。Install-Package IronBarcode'または'dotnet add package IronBarcode'でインストールしてください。コード中のusingディレクティブは'using IronBarcode;'である。

IronBarcodeはBarcodeScanning.MAUIと比べてどのようにDockerデプロイを簡素化しますか?

IronBarcodeは外部SDKファイルやマウントされたライセンス設定のないNuGetパッケージです。Dockerでは、IRONBARCODE_LICENSE_KEY環境変数を設定すると、パッケージが起動時にライセンス検証を処理します。

IronBarcodeはBarcodeScanning.MAUIから移行した後、すべてのバーコードフォーマットを自動的に検出しますか?

IronBarcodeは、サポートされているすべてのフォーマットのシンボルを自動検出します。明示的なBarcodeTypesの列挙は必要ありません。フォーマットが既に知られていて、パフォーマンスが重要な場合、BarcodeReaderOptionsは最適化として検索空間を制限することができます。

IronBarcodeは別のライブラリなしでPDFからバーコードを読み取ることができますか?

BarcodeReader.Read("document.pdf")は、PDFファイルをネイティブに処理します。結果には、見つかった各バーコードの PageNumber、Format、Value、および Confidence が含まれます。外部のPDFレンダリングステップは必要ありません。

IronBarcodeはどのようにパラレルバーコード処理を行うのですか?

IronBarcodeの静的メソッドはステートレスでスレッドセーフです。Parallel.ForEachをスレッドごとのインスタンス管理なしにファイルリスト上で直接使用します。BarcodeReaderOptions.MaxParallelThreadsは内部のスレッドバジェットを制御します。

BarcodeScanning.MAUIからIronBarcodeに移行すると、どのような結果プロパティが変更されますか?

一般的なリネーム:BarcodeValueはValueに、BarcodeTypeはFormatに。IronBarcodeの結果にはConfidenceとPageNumberも追加されます。ソリューション全体の検索と置換は、既存の結果処理コードで名前の変更を処理します。

CI/CDパイプラインでIronBarcodeのライセンスを設定するには?

IRONBARCODE_LICENSE_KEYをパイプラインシークレットとして保存し、アプリケーションの起動コードにIronBarCode.License.LicenseKeyを割り当てます。1つのシークレットで、開発環境、テスト環境、ステージング環境、本番環境を含むすべての環境をカバーできます。

IronBarcodeはカスタムスタイルのQRコード生成に対応していますか?

はい。QRCodeWriter.CreateQrCode()は、ChangeBarCodeColor()によるカスタムカラー、AddBrandLogo()によるロゴ埋め込み、設定可能なエラー訂正レベル、PNG、JPG、PDF、ストリームなどの複数の出力形式をサポートしています。

Curtis Chau
テクニカルライター

Curtis Chauは、カールトン大学でコンピュータサイエンスの学士号を取得し、Node.js、TypeScript、JavaScript、およびReactに精通したフロントエンド開発を専門としています。直感的で美しいユーザーインターフェースを作成することに情熱を持ち、Curtisは現代のフレームワークを用いた開発や、構造の良い視覚的に魅力的なマニュアルの作成を楽しんでいます。

開発以外にも、CurtisはIoT(Internet of Things)への強い関心を持ち、ハードウェアとソフトウェアの統合方法を模索しています。余暇には、ゲームをしたりDiscordボットを作成したりして、技術に対する愛情と創造性を組み合わせています。

アイアンサポートチーム

私たちは週5日、24時間オンラインで対応しています。
チャット
メール
電話してね