【Flutter】OpenAIで画像を生成する

対象者

  • Flutterをしている人
  • OpenAIを使用して、画像の自動生成を行いたい人

今回のアプリの画面

アプリの画面

APIキーを取得する

  • https://openai.com/に行く
  • アカウントを作成する
  • 右上のアカウントのマークを押し、リストの中から「View API keys」を選択する
  • 「API Keys」にある「+ Create new secret key」を押す
  • API Keyが作られるので、コピーする(生成時にしか、コピーはできないと思われる)

インストール

flutter pub add dart_openai
flutter pub get

実装

OpenAIの画像生成の実験のため、非常に簡易的な実装になっております。画像生成用のキーワードが決め打ちです。

インポート

import 'package:dart_openai/openai.dart';

OpenAIのAPIキーを設定

OpenAI.instanceにアクセスする前に、APIキーを設定します

OpenAI.apiKey = kOpenApiKey;

画像の生成

画像を生成します。生成に時間が掛かるため非同期です。Future型を受け取ります。

  • prompt: 画像生成のための文章
  • n: 生成する画像の数
  late final Future<OpenAIImageModel> futureImages =
     OpenAI.instance.image.create(
   prompt: '三匹の子猫',
   n: 2,
 );

取得した画像の表示

画像生成時に取得したFuture型の中からデータを取り出して、画面に表示します。表示時に結構時間が掛かります(私の環境では40秒弱)。
ぱっと見、画像生成自体より、画像のダウンロードか表示に時間が掛かってそう。

FutureBuilder<OpenAIImageModel>(
     future: futureImages,
     builder:
   	  (BuildContext context, AsyncSnapshot<OpenAIImageModel> snapshot) {

   	final images = snapshot.data!.data;
   	return ListView.builder(
   		itemCount: images.length,
   		itemBuilder: (context, index) {
   		  return Image.network(images[index].url);
   		});
     },
   ),

全ソース

全ソースを置いておきます。こちらにもあります。

import 'package:flutter/material.dart';
import 'package:dart_openai/openai.dart';

const kOpenApiKey = '[OpenAIのAPIキー]';

void main() {
 OpenAI.apiKey = kOpenApiKey;

 runApp(const MyApp());
}

class MyApp extends StatelessWidget {
 const MyApp({Key? key}) : super(key: key);

 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     title: 'Flutter Demo',
     theme: ThemeData(
       primarySwatch: Colors.blue,
     ),
     home: const MyHomePage(title: 'Flutter OpenAI Demo'),
   );
 }
}

class MyHomePage extends StatefulWidget {
 const MyHomePage({Key? key, required this.title}) : super(key: key);

 final String title;

 @override
 State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
 late final Future<OpenAIImageModel> futureImages =
     OpenAI.instance.image.create(
   prompt: '三匹の子猫',
   n: 2,
 );

 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(
       title: Text(widget.title),
     ),
     body: Center(
       child: FutureBuilder<OpenAIImageModel>(
         future: futureImages,
         builder:
             (BuildContext context, AsyncSnapshot<OpenAIImageModel> snapshot) {
           if (snapshot.hasError) {
             return Text('エラー:${snapshot.error!.toString()}');
           }
           if (!snapshot.hasData) {
             return const CircularProgressIndicator.adaptive();
           }

           final images = snapshot.data!.data;
           return ListView.builder(
               itemCount: images.length,
               itemBuilder: (context, index) {
                 return Image.network(images[index].url);
               });
         },
       ),
     ),
   );
 }
}

エラー

You must set the api key before accessing the instance of this class.

APIキーの設定を忘れてます

Your request was rejected as a result of our safety system

色々理由はあるとは思いますが、文章が解釈できなかった場合にも発生します。
「かわいい男の娘」で発生しました。(「男の娘」では、男と娘が表示されました) OpenAI様はオタク文化には造詣が深くないようです。

まとめ

FlutterでOpenAIの画像生成を使う方法を紹介しました。
リアルタイムではちょっと時間が掛かりますが、色々と使い道はありそうですね。

参考