single.php

C# WinUI3で画像から文字を取得するアプリを作成する方法

C# WinUI 3アプリを作っていく途中で、調べたことを忘録的に投稿します。今回はWinUI3プロジェクトで、[Windows.Media.Ocr]を利用して画像から文字を取得するアプリの実装方法です。

この記事は、Microsoft公式ページの「OcrEngine クラス」を参考に書いています。

画像ファイルから文字認識

今回は、こんな感じで文字が記された画像ファイルに選択させると

画像内の文字をテキストとして表示するアプリを作ります。

WinUI プロジェクトの作成

今回は[WinUI]プロジェクトでアプリを作成していきます。

具体的には、次の手順で行います。

1.[新しいプロジェクトの作成]画面で[空のアプリ、パッケージ化(デスクトップのWinUI 3)]を選択して[次へ]をクリックします。

2.[新しいプロジェクトを構成します]画面で[プロジェクト名]を設定して[作成]をクリックします。

3. 新しい[WinUI 3]アプリのプロジェクトが作成されます。

4. 実行させると[WinUI Desktop]画面が表示されます。

ファイル選択機能の実装

OCRで利用する画像を選択する機能を追加していきます。

具体的には、次の手順で行います。

1.[ソリューション エクスプローラー]画面で[MainWindow,xaml.cs]を選択して表示された画面で[Windows.Storage.Pickers]アセンブリをを追加します。

using Windows.Storage.Pickers;

2.[myButton_Click]イベントを編集して[開く]画面を表示するコードを追加します。

private async void myButton_Click(object sender, RoutedEventArgs e)
{
//  myButton.Content = "Clicked";

    var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
    var picker = new Windows.Storage.Pickers.FileOpenPicker
    {
        ViewMode = PickerViewMode.Thumbnail,
        SuggestedStartLocation = PickerLocationId.PicturesLibrary
    };
    picker.FileTypeFilter.Add(".jpg");

    WinRT.Interop.InitializeWithWindow.Initialize(picker, hwnd);

    var file = await picker.PickSingleFileAsync();

    var messageDialog = new Windows.UI.Popups.MessageDialog(file.path)
    {
        DefaultCommandIndex = 0,
        CancelCommandIndex = 0,
    };
    messageDialog.Commands.Add(new Windows.UI.Popups.UICommand("OK"));

    WinRT.Interop.InitializeWithWindow.Initialize(messageDialog, hwnd);

    await messageDialog.ShowAsync();
}

3. 編集したコードを実行して[Click Me]部分をクリックします。

4. 表示された[開く]画面で適当なJPG形式ファイルを選択します。

5. 選択したファイルの場所がメッセージボックスで表示されます。

画像からテキストを認識する機能の実装

[Windows.Media.Ocr]を利用して選択した画像からテキストを認識する機能を追加していきます。

具体的には、次の手順で行います。

1.[ソリューション エクスプローラー]画面で[MainWindow,xaml.cs]を選択して表示された画面の先頭部分に[Windows.Media.Ocr]アセンブリなどを追加します。

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;

using System.Windows;
using Microsoft.Win32;
using Windows.Media.Ocr;
using Windows.Storage.Streams;
using System.Threading.Tasks;
using Windows.Graphics.Imaging;
using Windows.Storage.Pickers;

1. 新しく[OCRfromImage]関数を追加します。

private async Task<string> OCRfromImage(string imagePath)
{
    try
    {
        byte[] imageBytes = File.ReadAllBytes(imagePath);
        IBuffer buffer = imageBytes.AsBuffer();
        SoftwareBitmap softBitmap;
        using (var stream = new InMemoryRandomAccessStream())
        {
            await stream.WriteAsync(buffer);
            stream.Seek(0);
            var bmpdecoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(stream);
            softBitmap = await bmpdecoder.GetSoftwareBitmapAsync();
        }
        OcrEngine ocrEngine = OcrEngine.TryCreateFromUserProfileLanguages();
        OcrResult ocrRecognize = await ocrEngine.RecognizeAsync(softBitmap);
        string ocrResult = ocrRecognize.Lines.Select(line => line.Text).Aggregate((current, next) => current + Environment.NewLine + next);

        return ocrResult;
    }
    catch (Exception ex)
    {
        return ex.Message;
    }
}

2. [myButton_Click]イベントを編集して[OCRfromImage]関数を呼び出します。

private async void myButton_Click(object sender, RoutedEventArgs e)
{
//  myButton.Content = "Clicked";

    var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
    var picker = new Windows.Storage.Pickers.FileOpenPicker
    {
        ViewMode = PickerViewMode.Thumbnail,
        SuggestedStartLocation = PickerLocationId.PicturesLibrary
    };
    picker.FileTypeFilter.Add(".jpg");

    WinRT.Interop.InitializeWithWindow.Initialize(picker, hwnd);

    var file = await picker.PickSingleFileAsync();

    string ocrResult = await OCRfromImage(file.Path);

    var messageDialog = new Windows.UI.Popups.MessageDialog(ocrResult)
    {
        DefaultCommandIndex = 0,
        CancelCommandIndex = 0,
    };
    messageDialog.Commands.Add(new Windows.UI.Popups.UICommand("OK"));

    WinRT.Interop.InitializeWithWindow.Initialize(messageDialog, hwnd);

    await messageDialog.ShowAsync();
}

3. 文字を追加した画像ファイルを用意します。

4. 編集したコードを実行して[Click Me]部分をクリックします。

4. 表示された[開く]画面で用意したJPG形式ファイルを選択します。

5. 画像内の文字がメッセージボックスに表示されます。

まとめ

今回は短い記事ですが、Visual StudioのWinUI3プロジェクトで、[Windows.Media.Ocr]を利用して画像からテキストを認識する機能の実装方法を紹介しました。

C#のアプリで文字を記載した画像ファイルからテキストを認識したい人の参考になれば幸いです。

スポンサーリンク

最後までご覧いただき、ありがとうございます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です