SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

マルチターゲットアプリ開発の新しいアプローチ~.NET 9 新テンプレートの基本~

.NET MAUI BlazorでAI画像生成アプリ構築。OpenAIのAPIで本番実装に移行しよう

マルチターゲットアプリ開発の新しいアプローチ~.NET 9 新テンプレートの基本~ 第3回


エラーハンドリングの改善

 APIを使用する際には、ネットワーク接続の問題や使用制限などのエラーが発生する可能性があります。そこで、ユーザーに適切なエラーメッセージを表示できるように、エラー処理を改善しましょう。

UIコンポーネントの変更

 ImageGeneration.razorのC#コード部分に、エラーメッセージを表示するための変数を追加し、処理を変更します。

[リスト6]ImageGeneration.razorの一部
// エラーメッセージ用の変数 (1)
private string errorMessage = "";

private async Task GenerateImage()
{
    // 入力がない場合は何もしない
    if (string.IsNullOrWhiteSpace(prompt)) return;
    
    isGenerating = true;
    errorMessage = ""; // エラーメッセージをクリア
    try
    {
        // サービスを使用して画像を生成
        imageUrl = await ImageService.GenerateImageAsync(prompt);
    }
    catch (Exception ex)
    {
        // エラーメッセージを設定 (2)
        errorMessage = $"画像生成中にエラーが発生しました: {ex.Message}";
    }
    finally { isGenerating = false; }
}

 ImageGeneration.razorに、エラーメッセージを保持する変数(errorMessage)を追加します(1)。GenerateImageメソッドでは、プロンプト入力値の検証後、画像生成処理を開始します。例外が発生した際には、エラーメッセージを設定します(2)。また、finallyブロックでは、生成状態フラグをリセットするようにしています。

HTMLの追加

 HTMLマークアップ部分にも、エラーメッセージを表示するセクションを追加します。

[リスト7]エラーメッセージ表示用HTML
@if (!string.IsNullOrEmpty(errorMessage))
{
  <div class="alert alert-danger mt-3">@errorMessage</div>
}

 エラーメッセージがある場合のみ、Bootstrapのalertコンポーネントを使用して、赤い警告ボックスで表示します。

画像生成オプションの追加

 DALL-E 3 APIでは、オプションを指定して画像生成をカスタマイズできます。今回は、サイズと品質を変更できるようにしてみましょう。

サービスインターフェイスの更新

 まず、IImageGenerationServiceインターフェイスを拡張して、オプションを指定できるようにします。

[リスト8]IImageGenerationService.csの一部
public interface IImageGenerationService
{
    // オプション指定での画像生成 (1)
    Task<string> GenerateImageAsync(string prompt, int quality = 0, int size = 0);
}

 既存のメソッドを、オプションの引数を持つメソッドに変更しました(1)。

サービス実装の更新

 OpenAIImageServiceクラスを更新して、オプション対応のメソッドを実装します。

[リスト9]OpenAIImageService.csの一部
public async Task<string> GenerateImageAsync(string prompt, int quality, int size)
{
    try
    {
        // オプションを示す数値(0、1など)を変換する (1)
        var gsize = size switch
        {
            1 => GeneratedImageSize.W1792xH1024,
            2 => GeneratedImageSize.W1024xH1792,
            _ => GeneratedImageSize.W1024xH1024
        };

        var gquality = quality switch
        {
            1 => GeneratedImageQuality.High,
            _ => GeneratedImageQuality.Standard
        };

        // リクエストを作成して実行 (2)
        var options = new ImageGenerationOptions
        {
            Size = gsize,
            Quality = quality,
            ResponseFormat = GeneratedImageFormat.Uri,  // URLを返す
            Style = GeneratedImageStyle.Vivid           // 画像スタイル
        };

        var result = await _client.GenerateImageAsync(prompt, options);
        return result.Value.ImageUri.ToString();
    }
    catch (Exception ex)
    {
        Console.WriteLine($"画像生成エラー: {ex.Message}");
        throw;
    }
}

 引数のオプションを示す数値から、それぞれOpenAI APIで使用する型(GeneratedImageSize、GeneratedImageQuality)に変換しています(1)。各オプション値をリクエストに適用し、APIを呼び出して画像を生成します(2)。

UIでのオプション選択

 UIコンポーネントを更新して、ユーザーが画像サイズと品質を選択できるようにします。

[リスト10]ImageGeneration.razorの一部
<div class="form-group">
  <label for="prompt">プロンプト</label>
~略~
</div>
<div class="form-group mt-2">
  <label for="imageSize">画像サイズ</label>
  <select id="imageSize" class="form-control" @bind="selectedSize">
    <option value="0">正方形 (1024x1024)</option>
    <option value="1">横長 (1792x1024)</option>
    <option value="2">縦長 (1024x1792)</option>
  </select>
</div>
<div class="form-group mt-2">
  <label for="imageQuality">品質</label>
  <select id="imageQuality" class="form-control" @bind="selectedQuality">
    <option value="0">標準</option>
    <option value="1">高品質</option>
  </select>
</div>

 UIにサイズと品質を選択するためのドロップダウンリストを追加しました。@bindディレクティブで、選択された値をC#の変数に直接バインドしています。ユーザーが選択を変更すると、対応するC#変数の値も自動的に更新されます。この値が、さきほどのGenerateImageAsyncメソッドの引数になります。

 C#コード部のGenerateImageメソッドも修正して、選択されたオプションを使用するようにします。

[リスト11]ImageGeneration.razorの一部
private int selectedSize = 0;
private int selectedQuality = 0;

private async Task GenerateImage()
{
~略~
    try
    {
        imageUrl = await ImageService.GenerateImageAsync(prompt,  selectedSize, selectedQuality);
    }
~略~
}

 サイズと品質のオプション値を保持する変数を追加し、画像生成時にサービスメソッドに渡しています。

動作確認

 Webアプリ、MAUIアプリの両方で同じように動作するか、ビルドして実行してみましょう。

画像生成のテスト

 「画像生成」ページで、プロンプトを入力して「画像を生成」ボタンをクリックします。たとえば「青空を背景に咲く桜の木」などとを入力してみましょう。しばらく待つと、OpenAI APIによって生成された画像が表示されるはずです。

画像生成結果の表示
画像生成結果の表示

 さまざまなサイズや品質オプションを試してみて、表示が変更されることを確認してみましょう。なお、品質を高くすると、処理時間とAPIコスト(料金)が増加することに注意してください。

最後に

 今回は、OpenAIのImage Generation APIを活用した画像生成ロジックを実装しました。DIを使うことで、前回のモックサービスから実際のAPI実装へ、簡単に差し替えられました。

 次回は「モバイル環境への適用」として、モバイルデバイスでアプリを実行するための設定について解説する予定です。

この記事は参考になりましたか?

マルチターゲットアプリ開発の新しいアプローチ~.NET 9 新テンプレートの基本~連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 高江 賢(タカエ ケン)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/22376 2025/10/21 11:29

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング