2025/07/20

つないでみよう:#28)画像生成 AI DALL-E3 - Base64 文字列を画像ファイルに変換

OpenAI 社の DALL-E3 を API で利用して画像を生成するシリーズの最終回です。今回はレスポンスの JSON に含まれる画像をファイルとして抽出する部分を作成します。


メインルーチンの修正

画像ファイルを取得するには大きく分けて2つの処理が必要です。

まず、前回紹介したレスポンスの中から画像データの文字列だけを取得します。2つ目の処理では。画像データを画像ファイルに変換します。

この流れに沿ってメインルーチンを構築します。

Sub Initialize
         ・・・(省略)・・・
   'API をコール
   Set jnavResponce = xAskGPT(sJSON_Post)
   Call xSetRT(nd, "JSON_Responce", jnavResponce.Stringify())


   '生成画像を Base64 文字列で取得
   sBase64 = xGetImage_Base64(jnavResponce)

   'Base64 画像をファイルとして保存
   Call xDownloadImage(sBase64, "c:\Temp\DALL-E3#28.jpg")

   Call nd.save(True, False)
End Sub


画像データの取得

レスポンスの JSON はこのような構造でした。

ここから base64_json の値を取得する関数 xGetImage_Base64 を作成します。引数はレスポンスの JSON 全体で、戻り値が画像データです。

関数内の処理では、data ノードが配列になっている点に注意が必要です。

Function xGetImage_Base64(vjnavResponce As NotesJSONNavigator) As String
   Dim je As NotesJSONElement
   Dim ja As NotesJSONArray
   Dim jeData As NotesJSONElement
   Dim jobj As NotesJSONObject
   Dim jeBase64 As NotesJSONElement
   Dim sResponce As String

   ' data を検索
   Set je = vjnavResponce.GetElementByName("data")

   ' data は配列なので NotesJSONArray で受ける
   Set ja = je.Value

   If ja.Size > 0 Then
      '配列の 1 件目を取得
      Set jeData = ja.GetFirstElement()
      Set jobj = jeData.Value

      ' b64_json を検索し値( = 画像)を取得
      Set jeBase64 = jobj.GetElementByName("b64_json")
      xGetImage_Base64 = jeBase64.Value
   End If
End Function


画像データの変換と保存

メインルーチンがコールする2つ目の関数です。Base64 画像をデコードする部分と画像ファイルとして保存する処理に分かれます。それぞれの処理はサブ関数化されています。

Function xDownloadImage(ByVal vsBase64 As String, ByVal vsFP As String) As Boolean
   Dim nst As NotesStream

   'Base64 画像をファイルとして保存
   Set nst = xns.CreateStream()
   Call Base64ToBinary(vsBase64, nst)
   Call StreamToImageFile(nst, vsFP)
End Function


サブ関数は別の連載記事『DXL Step-by-Step:#9)DXL 内の画像のダウンロード』で紹介したもので、そのまま再利用します。今回は関数のみ転載しますので、詳細を知りたい方は、上記リンクをご確認ください。


◇ Base64 のデコード

%REM
   Sub Base64ToBinary
   Description: Given a string of base64-encoded data, write into a binary stream we are passed.
      This is done rather than creating the stream here and returning it, so that you can
   stream directly into a file if you choose.
%END REM

Sub Base64ToBinary(strBase64$, streamOut As NotesStream)
   ' Given a string of base64 encoded data, this routine decodes and writes the original binary data into a NotesStream
   Dim doc As NotesDocument
   Dim mime As NotesMIMEEntity
   Dim streamIn As NotesStream
   Dim db As NotesDatabase
   Dim session As New NotesSession

   Set db = session.CurrentDatabase
   Set doc = db.CreateDocument
   Set mime = doc.CreateMIMEEntity("Body") ' the mime classes already know how to do this conversion,
   Set streamIn = session.CreateStream
   Call streamIn.WriteText(strBase64)
   streamIn.Position = 0
   Call mime.SetContentFromText(streamIn, "binary", ENC_BASE64)
   Call mime.GetContentAsBytes(streamOut, True) ' decode as you stream out the data.
End Sub

※ OpenNTF の LotusScript Gold Collection プロジェクトから拝借


◇ 画像をファイルとして保存

Sub StreamToImageFile(vnstImage As NotesStream, ByVal vsFP As String)
   Dim nstOut As NotesStream

   On Error Resume Next
   Kill vsFP '存在してたら削除

   Set nstOut = xns.CreateStream()
   Call nstOut.Open(vsFP)

   vnstImage.Position = 0
   Do Until vnstImage.Position >= vnstImage.Bytes
      Call nstOut.Write(vnstImage.Read(16000))
   Loop
End Sub


テスト実行

エージェントが完成したらテスト実行します。前回のテストと同様に『上司と部下が会議室で本気で議論しているシーンを少年漫画のバトルシーンのようなタッチで描いてください。』と指示を出すと以下のような画像が作成されました。


まとめ

今回は画像生成 AI の OpenAI 社の DALL-E3 を API で利用する方法を紹介しました。画像1枚あたりの生成コストは $0.04(約 6 円、今回の設定の場合)と比較的安価です。この金額で、上記のようなクオリティの画像が生成できるのですから、十分に利用価値があるといえるでしょう。

今後はプロンプトエンジニアリングの技術を磨き、より理想に近い画像を生成できるようにしていきたいですね。


前回 連載:つないでみよう


0 件のコメント:

コメントを投稿