teratail header banner
teratail header banner
質問するログイン新規登録
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

1回答

2076閲覧

C# StrageFolder.GetFolderFromPathAsync(@path)で動作が止まる

AnzuFutaba

総合スコア3

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

1グッド

0クリップ

投稿2023/01/02 09:06

1

0

前提

C# フォームアプリケーションで、BitmapをSoftWareBitmapに変換するための処理を書いています。その際、一時的にBitmapを保存するフォルダをStrageFolder.GetFolderFromPathAsyncで取得したのですが、そこで処理が止まってしまいます。(フォームが固まる)

実現したいこと

  • StrageFolderが正常に動作するようにする

該当のソースコード

C#

1public async Task<SoftwareBitmap> GetSoftwareBitmap(Bitmap _bitmap) 2 { 3 var folder = Directory.GetCurrentDirectory(); 4 var image_name = "tmp.png"; 5 StorageFolder appFolder = await StorageFolder.GetFolderFromPathAsync(@folder); 6 7 _bitmap.Save(folder + "\\" + image_name, System.Drawing.Imaging.ImageFormat.Png); 8 SoftwareBitmap softwareBitmap; 9 var bmpFile = await appFolder.GetFileAsync(image_name); 10 11 using (IRandomAccessStream stream = await bmpFile.OpenAsync(FileAccessMode.Read)) 12 { 13 Windows.Graphics.Imaging.BitmapDecoder decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(stream); 14 softwareBitmap = await decoder.GetSoftwareBitmapAsync(); 15 } 16 17 File.Delete(folder + "\\" + image_name); 18 return softwareBitmap; 19 }

試したこと

途中にConsole.WriteLineを表示させて止まる場所を調べたところ、当該箇所でした。

補足情報(FW/ツールのバージョンなど)

Windows11 C# VisualStudio 2022

TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

コードの癖からこちらを参考にされていると思います(参考コードは質問に明記してください)
【C#】Windows10のOCRを使用する - かくすけのいろいろ作るブログ

WinRTを呼び出すための準備はどのようになさっていますか?
このあたり変更が度々あり、Webの情報は古くなっていることが多いです。

.NET6以降であれば、TFMにバージョンを追加するだけですぐ使えます。
デスクトップ アプリで Windows ランタイム API を呼び出す - Windows apps | Microsoft Learn

.NET6より前または.NET Frameworkは、Microsoft.Windows.SDK.ContractsをNuGetします。
デスクトップ アプリで Windows ランタイム API を呼び出す - Windows apps | Microsoft Learn

.NET7と.NET Framework4.8でやってみましたが、問題を再現できませんでした。


変換が目的であれば、そもそもファイルに書き出す必要もありません。
方法: .NET Framework ストリームと Windows ランタイム ストリームの間で変換を行う (Windows のみ) | Microsoft Learn

cs

1using System; 2using System.Diagnostics; 3using System.Drawing; 4using System.Drawing.Imaging; 5using System.IO; 6using System.Threading.Tasks; 7using System.Windows.Forms; 8using Windows.Graphics.Imaging; 9using Windows.Media.Ocr; 10using Windows.Storage; 11 12namespace Qsf9ytkqkypzrbp 13{ 14 public partial class Form1 : Form 15 { 16 public Form1() 17 { 18 InitializeComponent(); 19 20 var button1 = new Button 21 { 22 Parent = this, 23 Dock = DockStyle.Fill, 24 }; 25 button1.Click += button1_Click; 26 } 27 28 private async void button1_Click(object sender, EventArgs e) 29 { 30 var softwareBitmap = await GetSoftwareBitmapAsync(CaptureScreen()); 31 var ocrResult = await RecognizeTextAsync(softwareBitmap); 32 Debug.WriteLine(ocrResult.Text); 33 34 softwareBitmap = await GetSoftwareBitmapAsync2(CaptureScreen()); 35 ocrResult = await RecognizeTextAsync(softwareBitmap); 36 Debug.WriteLine(ocrResult.Text); 37 } 38 39 private Bitmap CaptureScreen() 40 { 41 var size = Screen.PrimaryScreen.Bounds.Size; 42 var bitmap = new Bitmap(size.Width, size.Height); 43 using (var g = Graphics.FromImage(bitmap)) 44 { 45 g.CopyFromScreen(new Point(), new Point(), bitmap.Size); 46 } 47 return bitmap; 48 } 49 50 private async Task<SoftwareBitmap> GetSoftwareBitmapAsync(Bitmap bitmap) 51 { 52 var folder = Directory.GetCurrentDirectory(); 53 var name = "tmp.png"; 54 bitmap.Save(Path.Combine(folder, name), ImageFormat.Png); 55 56 var appFolder = await StorageFolder.GetFolderFromPathAsync(folder); 57 var bmpFile = await appFolder.GetFileAsync(name); 58 59 SoftwareBitmap softwareBitmap; 60 using (var stream = await bmpFile.OpenAsync(FileAccessMode.Read)) 61 { 62 var decoder = await BitmapDecoder.CreateAsync(stream); 63 softwareBitmap = await decoder.GetSoftwareBitmapAsync(); 64 } 65 66 File.Delete(Path.Combine(folder, name)); 67 return softwareBitmap; 68 } 69 70 private async Task<SoftwareBitmap> GetSoftwareBitmapAsync2(Bitmap bitmap) 71 { 72 using (var memoryStream = new MemoryStream()) 73 { 74 bitmap.Save(memoryStream, ImageFormat.Png); 75 using (var stream = memoryStream.AsRandomAccessStream()) 76 { 77 var decoder = await BitmapDecoder.CreateAsync(stream); 78 return await decoder.GetSoftwareBitmapAsync(); 79 } 80 } 81 } 82 83 private async Task<OcrResult> RecognizeTextAsync(SoftwareBitmap snap) 84 { 85 var ocrEngine = OcrEngine.TryCreateFromUserProfileLanguages(); 86 return await ocrEngine.RecognizeAsync(snap); 87 } 88 } 89}

投稿2023/01/02 11:57

編集2023/01/02 21:49
TN8001

総合スコア10111

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

AnzuFutaba

2023/01/03 01:45

ご回答いただき、また検証までしていただき本当にありがとうございました。 Windows SDKから以下のようなサイトを参考にしながら参照を追加しておりました。 (https://marunaka-blog.com/wpf-ocr-windows10/2260/) 提示いただいたコードをもとに、自身のコードを見つめ直すと、画像変換用のメソッドでデッドロックを起こしていたようでした。(awaitの付け忘れ) 修正すると動くようになりました。ありがとうございました! 引用に関して、今後注意いたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問