🎨

Next.js14でDall-E(open ai)を使えるようにしてみた(その2)

2023/12/20に公開

こんにちは、近藤です。
commmune Advent Calendar 2023 11日目の記事は『Next.js14でDall-E(open ai)を使えるようにしてみた(その2)』です

この記事は、先に公開された『Next.js14でDall-E(open ai)を使えるようにしてみた(その1)』の続きです。

Dall-Eとは、OpenAIによって開発されたAIプログラムで、テキストの説明から画像を生成する能力を持っています。また、Dall-Eはapiが公開されており、アプリケーションに組み込むことが可能です。

前回の記事では、Next.js 14でDall-Eを使えるようにする方法を紹介しました。今回は、既に実装された機能に拡張を行います。具体的には、「画像とコメントを送ると、そのコメントからイメージを画像に反映するAPI」の実装を目指します。例えば、「森の画像に木こりを追加して」というリクエストに応じて、画像を編集することです。

実際にこのAPIを実装してみた結果、期待通りの成果は得られませんでした。詳細は後述します。
そのため「コメントから規定の画像に対し、コメントを反映した画像に修正するAPI」に方針を変更しました。

成果物

今回作成したリポジトリはこちらです:GitHubリポジトリ

以下のオリジナル画像に対して、
original

"a tiger swimming a pool"というプロンプトを入力すると、以下の画像が出力されました。
generated

虎が泳いでいる様子がぼんやりと見えます。

実装方法

アプリの概要などは前回のNext.js14でDall-E(open ai)を使えるようにしてみた(その1)を参照ください。

今回は早速実装方法の説明を行います。
open-aiのドキュメントを参照し、以下のような関数を作成しました。
(前回同様2023年12月時点ではドキュメント通りの実装ではうまくいかないので注意してください)

export const editImageWithDallE2 = async (textPrompt: string) => {
  const image = await convertToPngRGBA("./public/original.png");
  const mask = await convertToPngRGBA("./public/mask.png");
  const response = await openai.images.edit({
    image,
    prompt: textPrompt,
    n: 1,
    mask,
    model: "dall-e-2",
    size: "512x512",
  });
  return response.data[0].url;
};

imageについて

編集する画像ファイルです。
今回は以下のような画像ファイルを使用しました。
image

maskについて

imageの一部をトリミングした画像ファイルです。トリミングすることで編集される場所を固定できます。なくても動作します。今回は以下の画像を使用しました。
mask

convertToPngRGBAについて

pngがRGB形式だとエラーが出るので、Jimpを使用してRGBA形式に変換しています。

import Jimp from "jimp";
import fs from "fs";

export const convertToPngRGBA = async (path: string) => {
  let jImage = await Jimp.read(path);

  // Ensure image has an alpha channel
  if (!jImage.hasAlpha()) {
    jImage = jImage.opacity(1);
  }

  // Convert to RGBA format
  jImage = jImage.rgba(true);

  // Write the processed image to a temporary file
  const tempFilePath = "/tmp/processed_image.png";
  await jImage.writeAsync(tempFilePath);

  return fs.createReadStream(tempFilePath);
};

ここは結構詰まったので、もしこのapiを利用する場合は注意してください

maskの有無による成果

どちらも共通でa tiger swimming in the poolという文言で実行しました。

maskなし

no mask

maskあり

use mask

どちらもちゃんとプールで虎が泳いでますね

終わりに

今回もOpenAIのapiのプライシングが従量課金なので、デプロイは行いませんでした。

私の期待としては、プールで泳いでいる虎を画像に挿入してください。というような指示でもう少しリアリティのある画像を出力したかったのですが、添付した画像のように少しぼやけて出力されています。
また上記を出力するにも、なんどか試したりする必要がありました。

プロンプトをもう少し丁寧に作成すれば良い画像が作成できたのかもしれませんが、私が求めていたのは簡単なプロンプトでリアリティのある画像を出力してくれることだったので、期待通りの成果は得られませんでした。

余談

個人的に場所法という記憶術をもっと便利に使えるようなアプリケーションを開発しておりまして、このAPIが使用できるのではと考えていました。

場所法についてざっくり説明すると、自分の慣れ親しんだ場所を頭の中でイメージし、そこに記憶したいものを配置していくことでイメージとして記憶に残す方法です。

このAPIを利用し、慣れ親しんだ場所の写真とプロンプトで画像を作成し、脳内のイメージを具体化する機能を作成できるのではないかと考えていました。

APIがもう少し発展すれば、このアプリケーションに活用できると考えています。
現在はDall-E2(現時点の最新はDall-E3)が画像編集に利用できる唯一のAPIですし、OpenAIの開発スピードは凄まじいので、すぐに私のしたいことができるようになると思っています。

コミューン株式会社

Discussion