使用OpenAI DALL-E API开发AI图像生成React应用程序

使用OpenAI DALL-E API为AI图像生成构建React应用程序

在充满活力的技术领域中,创新不断塑造着可能的边界,而人工智能(AI)从未停止过吸引我们的想象力。

人工智能是指计算机系统对人类智能过程的模拟。这些过程包括学习、推理、解决问题、感知、语言理解和决策等任务。

如今,个人和公司已经开发并训练出了多个人工智能模型,可以比人类更好地实时执行某些任务。在人工智能的无数应用中,一个特别引人关注的领域是人工智能驱动的图像生成。

您正在构建的内容

本指南介绍如何构建一个 React 应用程序,通过 Node.js 后端与 OpenAI DALL-E API 无缝集成,并根据文本提示生成图像。

运行中的人工智能图像生成器

运行中的人工智能图像生成器,使用 DALL-E API 生成生动而富有创意的图像。

要参与本项目,您应具备以下条件

什么是 OpenAI DALL-E API?

OpenAI API 是一个基于云的平台,它允许开发者访问 OpenAI 预先训练好的人工智能模型,如 DALL-E 和 GPT-3(我们使用该模型在此 Git 仓库中的代码构建了 ChatGPT 克隆版)。它允许开发人员在程序中添加摘要、翻译、图像生成和修改等人工智能功能,而无需开发和训练自己的模型。

要使用 OpenAI API,请使用 Google 账户或电子邮件在 OpenAI 网站上创建一个账户,并获取一个 API 密钥。要生成 API 密钥,请单击网站右上角的 “Personal“,然后选择 “View API keys“。

创建 OpenAI API 密钥

创建 OpenAI API 密钥的过程。

单击 “Create new secret key” 按钮,并将密匙保存在某处。您将在本应用程序中使用它与 OpenAI 的 DALL-E API 进行交互。

设置开发环境

您可以从头开始创建 React 应用程序并开发自己的界面,也可以按照以下步骤获取我们的 Git 启动模板:

  1. 访问本项目的 GitHub 仓库
  2. 选择 “Use this template“>”Create a new repository“,将启动代码复制到 GitHub 账户中的仓库(选中复选框以包含所有分支)。
  3. 将仓库拉到本地电脑,然后使用命令切换到 starter-files 分支: git checkout starter-files
  4. 运行 npm install 命令安装必要的依赖项。

安装完成后,就可以在本地电脑上使用 npm run start 启动项目。这样,项目就可以在 http://localhost:3000/ 上运行了。

AI 图像生成器应用程序的用户界面

AI 图像生成器应用程序的用户界面,展示了人工智能在图像创建方面的强大功能。

在本项目中,我们为 React 应用程序添加了所有必要的依赖项。以下是已安装内容的概览:

  • file-server:该实用库简化了下载生成图片的过程。它与下载按钮相连,确保了流畅的用户体验。
  • uuid:该库为每张图片分配一个唯一标识。这可以防止图像共享相同的默认文件名,从而保持秩序和清晰度。
  • react-icons:该库集成到项目中,可以毫不费力地整合图标,增强应用程序的视觉吸引力。

React 应用程序的核心是 src 文件夹。这里存放着 Webpack 的基本 JavaScript 代码。让我们来了解一下 src 文件夹中的文件和文件夹:

  • assets:在此目录中,您可以找到整个项目中使用的图片和加载器 gif。
  • data:该文件夹包含一个 index.js 文件,可导出 30 个提示数组。这些提示可用于生成各种随机图片。请随意编辑。
  • index.css:这里存储了本项目中使用的样式。

了解 Utils 文件夹

在该文件夹中,index.js 文件定义了两个可重复使用的函数。第一个函数会随机选择描述可生成的各种图像的提示。

import { randomPrompts } from '../data';
export const getRandomPrompt = () => {
const randomIndex = Math.floor(Math.random() * randomPrompts.length);
const randomPrompt = randomPrompts[randomIndex];
return randomPrompt;
}

第二个函数利用 file-saver 依赖关系处理生成图像的下载。这两个函数的创建都是为了提供模块化和高效性,在需要时可以方便地导入到组件中。

import FileSaver from 'file-saver';
import { v4 as uuidv4 } from 'uuid';
export async function downloadImage(photo) {
const _id = uuidv4();
FileSaver.saveAs(photo, `download-${_id}.jpg`);
}

在上面的代码中,uuid 属性为每个生成的图像文件提供了一个唯一的 ID,因此它们不会有相同的文件名。

了解组件

组件是分隔开来的小代码块,使代码易于维护和理解。本项目创建了三个组件: Header.jsxFooter.jsxForm.jsx。主要组件是表单组件,在该组件中,输入被接收并传递到 App.jsx 文件,generateImage 函数被添加为 Generate Image 按钮的 onClick 事件。

在表单组件中,创建了一个状态来存储和更新提示。此外,您还可以通过点击随机图标来生成随机提示。这是通过 handleRandomPrompt 函数实现的,该函数使用了已设置的 getRandomPrompt 函数。当你点击图标时,它会获取随机提示并更新状态:

const handleRandomPrompt = () => {
const randomPrompt = getRandomPrompt();
setPrompt(randomPrompt)
}

了解 App.jsx 文件

大部分代码都在这里。所有组件都集中在这里。还有一个指定区域用于显示生成的图片。如果尚未生成图像,则会显示一个占位符图像(预览图像)。

在该文件中,有两种状态需要管理:

  • isGenerating: 用于跟踪图像当前是否正在生成。默认设置为 false。
  • generatedImage: 该状态存储已生成图像的相关信息。

此外,还导入了 downloadImage 实用程序函数,使您可以在单击 Download 按钮时触发生成图像的下载:

<button
className="btn"
onClick={() => downloadImage(generatedImage.photo)}
>

现在,您已经了解了启动文件并设置了项目。让我们开始处理这个应用程序的逻辑。

使用 OpenAI 的 DALL-E API 生成图像

要利用 OpenAI 的 DALL-E API 功能,您需要使用 Node.js 建立一个服务器。在该服务器中,您将创建一个 POST 路由。该路由将负责接收从 React 应用程序发送的提示文本,然后利用它生成图像。

要开始工作,请运行以下命令在项目目录中安装必要的依赖项:

npm i express cors openai

此外,将以下依赖项安装为开发依赖项。这些工具将帮助您设置 Node.js 服务器:

npm i -D dotenv nodemon

已安装的依赖项说明如下:

  • express: 该库有助于在 Node.js 中创建服务器。
  • cors: CORS 可促进不同域之间的安全通信。
  • openai: 通过该依赖关系,您可以访问 OpenAI 的 DALL-E API。
  • dotenv: dotenv 协助管理环境变量。
  • nodemon: nodemon 是一种开发工具,可监控文件的变化并自动重启服务器。

安装成功后,在项目根目录下创建 server.js 文件。所有服务器代码都将存放在这里。

server.js 文件中,导入刚安装的并将其实例化:

// Import the necessary libraries
const express = require('express');
const cors = require('cors');
require('dotenv').config();
const OpenAI = require('openai');
// Create an instance of the Express application
const app = express();
// Enable Cross-Origin Resource Sharing (CORS)
app.use(cors());
// Configure Express to parse JSON data and set a data limit
app.use(express.json({ limit: '50mb' }));
// Create an instance of the OpenAI class and provide your API key
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
// Define a function to start the server
const startServer = async () => {
app.listen(8080, () => console.log('Server started on port 8080'));
};
// Call the startServer function to begin listening on the specified port
startServer();

在上面的代码中,你需要导入必要的库。然后,使用 const app = express(); 建立一个 Express 应用程序实例。然后,启用 CORS。接下来,配置 Express 以处理传入的 JSON 数据,并指定数据大小限制为 50MB

随后,使用 OpenAI API 密钥创建 OpenAI 类实例。在项目根目录下创建 .env 文件,并使用 OPENAI_API_KEY 变量添加 API 密钥。最后,定义异步 startServer 函数并调用它来启动服务器。

现在你已经配置好了 server.js 文件。让我们创建一个 POST 路由,您可以在 React 应用程序中使用该路由与服务器交互:

app.post('/api', async (req, res) => {
try {
const { prompt } = req.body;
const response = await openai.images.generate({
prompt,
n: 1,
size: '1024x1024',
response_format: 'b64_json',
});
const image = response.data[0].b64_json;
res.status(200).json({ photo: image });
} catch (error) {
console.error(error);
}
});

在这段代码中,路由设置为 /api ,旨在处理传入的 POST 请求。在路由的回调函数中,您将使用 req.body 接收到从 React 应用程序发送的数据,特别是 prompt 值。

随后,会调用 OpenAI 库的 images.generate 方法。该方法接收所提供的提示并生成图像作为响应。n 等参数决定了要生成的图片数量(这里只有一张),size 指定了图片的尺寸,response_format 则指示了应提供的响应格式(本例中为 b64_json )。

生成图片后,从响应中提取图片数据并存储到 image 变量中。然后,使用 res.status(200).json({ photo: image }) 向 React 应用程序发送包含生成的图像数据的 JSON 响应,并将 HTTP 状态设置为 200(表示成功)。

如果在此过程中出现任何错误,将执行 catch 代码块中的代码,并将错误记录到控制台以便调试。

现在服务器已经准备就绪!让我们在 package.json 文件 scripts 对象中指定用于运行服务器的命令:

"scripts": {
"dev:frontend": "react-scripts start",
"dev:backend": "nodemon server.js",
"build": "react-scripts build",
},

现在运行 npm run dev:backend 时,服务器将在 http://localhost:8080/ 上启动,而运行 npm run dev:frontend 时,React 应用程序将在 http://localhost:3000/ 上启动。确保两者在不同的终端运行。

从 React 向 Node.js 服务器发出 HTTP 请求

App.jsx 文件中,您将创建一个 generateImage 函数,当点击 Form.jsx 组件中的 Generate Image(生成图片)按钮时触发该函数。该函数接受两个参数:来自 Form.jsx 组件的 promptsetPrompt

generateImage 函数中,向 Node.js 服务器发出 HTTP POST 请求:

const generateImage = async (prompt, setPrompt) => {
if (prompt) {
try {
setIsGenerating(true);
const response = await fetch(
'http://localhost:8080/api',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
prompt,
}),
}
);
const data = await response.json();
setGeneratedImage({
photo: `data:image/jpeg;base64,${data.photo}`,
altText: prompt,
});
} catch (err) {
alert(err);
} finally {
setPrompt('');
setIsGenerating(false);
}
} else {
alert('Please provide proper prompt');
}
};

在上面的代码中,您要检查 prompt 参数是否有值,然后将 isGenerating 状态设为 true ,因为操作正在开始。这将使加载器显示在屏幕上,因为在 App.jsx 文件中,我们有这段代码控制加载器的显示:

{isGenerating && (
<div> className="loader-comp">
<img src={Loader} alt="" className='loader-img' />
</div>
)}

接下来,使用 fetch() 方法,使用 http://localhost:8080/api 向服务器发出 POST 请求–这就是我们安装 CORS 的原因,因为我们正在与另一个 URL 上的 API 交互。我们使用提示作为消息正文。然后,提取 Node.js 服务器返回的响应,并将其设置为 generatedImage 状态。

一旦 generatedImage 状态有了值,图片就会显示出来:

{generatedImage.photo ? (
<img
src={generatedImage.photo}
alt={generatedImage.altText}
className="imgg ai-img"
/>
) : (
<img
src={preview}
alt="preview"
className="imgg preview-img"
/>
)}

这就是 App.jsx 文件的完整内容:

import { Form, Footer, Header } from './components';
import preview from './assets/preview.png';
import Loader from './assets/loader-3.gif'
import { downloadImage } from './utils';
import { useState } from 'react';
const App = () => {
const [isGenerating, setIsGenerating] = useState(false);
const [generatedImage, setGeneratedImage] = useState({
photo: null,
altText: null,
});
const generateImage = async (prompt, setPrompt) => {
if (prompt) {
try {
setIsGenerating(true);
const response = await fetch(
'http://localhost:8080/api',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
prompt,
}),
}
);
const data = await response.json();
setGeneratedImage({
photo: `data:image/jpeg;base64,${data.photo}`,
altText: prompt,
});
} catch (err) {
alert(err);
} finally {
setPrompt('');
setIsGenerating(false);
}
} else {
alert('Please provide proper prompt');
}
};
return (
<div className='container'>
<Header />
<main className="flex-container">
<Form generateImage={generateImage} prompt={prompt} />
<div className="image-container">
{generatedImage.photo ? (
<img
src={generatedImage.photo}
alt={generatedImage.altText}
className="imgg ai-img"
/>
) : (
<img
src={preview}
alt="preview"
className="imgg preview-img"
/>
)}
{isGenerating && (
<div className="loader-comp">
<img src={Loader} alt="" className='loader-img' />
</div>
)}
<button
className="btn"
onClick={() => downloadImage(generatedImage.photo)}
>
Download
</button>
</div>
</main>
<Footer />
</div>
);
};
export default App;

将您的全栈应用程序部署到 Kinsta

到目前为止,您已经成功构建了一个能与 Node.js 交互的 React 应用程序,这使它成为一个全栈应用程序。现在让我们将此应用程序部署到 Kinsta。

首先,配置服务器,以便为 React 应用程序构建过程中生成的静态文件提供服务。这可以通过导入 path 模块并使用它来提供静态文件来实现:

const path = require('path');
app.use(express.static(path.resolve(__dirname, './build')));

当您执行 npm run build && npm run dev:backend 命令时,您的全栈 React 应用程序将加载到 http://localhost:8080/。这是因为 React 应用程序已编译成 build 文件夹中的静态文件。然后,这些文件将作为静态目录并入 Node.js 服务器。因此,当您运行 Node 服务器时,就可以访问应用程序。

在将代码部署到您选择的 Git 提供商(Bitbucket、GitHub 或 GitLab)之前,请记住修改 App.jsx 文件中的 HTTP 请求 URL。将 http://localhost:8080/api 改为 /api ,因为 URL 将被预输入。

最后,在 package.json 文件中,为用于部署的 Node.js 服务器添加一个脚本命令:

"scripts": {
// …
"start": "node server.js",
},

接下来,按照以下步骤将代码推送到您首选的 Git 提供商,并将您的仓库部署到 Kinsta:

  1. MyKinsta 面板上登录您的 Kinsta 账户。
  2. 选择左侧边栏上的 Application ,然后单击 “Add Application” 按钮。
  3. 在出现的模态中,选择要部署的版本库。如果有多个分支,可以选择所需的分支并为应用程序命名。
  4. 从可用的数据中心位置中选择一个。
  5. OPENAI_API_KEY 添加为环境变量。Kinsta 会自动为你设置一个 Dockerfile。
  6. 最后,在启动命令字段中添加 npm run build && npm run start 。Kinsta 会从 package.json 安装应用程序的依赖项,然后构建并部署应用程序。

小结

小结在本指南中,您将学习如何利用 OpenAI 的 DALL-E API 的强大功能来生成图像。您还学会了如何使用 React 和 Node.js 构建基本的全栈应用程序。

人工智能的可能性是无限的,因为每天都有新的模型问世,您可以创建令人惊叹的项目,并将其部署到应用程序托管中。

评论留言