在充滿活力的技術領域中,創新不斷塑造著可能的邊界,而人工智慧(AI)從未停止過吸引我們的想象力。
人工智慧是指計算機系統對人類智慧過程的模擬。這些過程包括學習、推理、解決問題、感知、語言理解和決策等任務。
如今,個人和公司已經開發並訓練出了多個人工智慧模型,可以比人類更好地實時執行某些任務。在人工智慧的無數應用中,一個特別引人關注的領域是人工智慧驅動的影象生成。
您正在構建的內容
本指南介紹如何構建一個 React 應用程式,通過 Node.js 後端與 OpenAI DALL-E API 無縫整合,並根據文字提示生成影象。
執行中的人工智慧影象生成器,使用 DALL-E API 生成生動而富有創意的影象。
要參與本專案,您應具備以下條件
- 對 HTML、CSS 和 JavaScript 有基本瞭解
- React 和 Node.js 的基礎知識
- 計算機上安裝了 Node.js 和 npm(Node 包管理器)或 yarn
什麼是 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 金鑰的過程。
單擊 “Create new secret key” 按鈕,並將密匙儲存在某處。您將在本應用程式中使用它與 OpenAI 的 DALL-E API 進行互動。
設定開發環境
您可以從頭開始建立 React 應用程式並開發自己的介面,也可以按照以下步驟獲取我們的 Git 啟動模板:
- 訪問本專案的 GitHub 倉庫。
- 選擇 “Use this template“>”Create a new repository“,將啟動程式碼複製到 GitHub 賬戶中的倉庫(選中覈取方塊以包含所有分支)。
- 將倉庫拉到本地電腦,然後使用命令切換到 starter-files 分支:
git checkout starter-files
。 - 執行
npm install
命令安裝必要的依賴項。
安裝完成後,就可以在本地電腦上使用 npm run start
啟動專案。這樣,專案就可以在 http://localhost:3000/ 上執行了。
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.jsx、Footer.jsx 和 Form.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 元件的 prompt
和 setPrompt
。
在 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:
- 在 MyKinsta 面板上登入您的 Kinsta 賬戶。
- 選擇左側邊欄上的 Application ,然後單擊 “Add Application” 按鈕。
- 在出現的模態中,選擇要部署的版本庫。如果有多個分支,可以選擇所需的分支併為應用程式命名。
- 從可用的資料中心位置中選擇一個。
- 將
OPENAI_API_KEY
新增為環境變數。Kinsta 會自動為你設定一個 Dockerfile。 - 最後,在啟動命令欄位中新增
npm run build && npm run start
。Kinsta 會從 package.json 安裝應用程式的依賴項,然後構建並部署應用程式。
小結
小結在本指南中,您將學習如何利用 OpenAI 的 DALL-E API 的強大功能來生成影象。您還學會了如何使用 React 和 Node.js 構建基本的全棧應用程式。
人工智慧的可能性是無限的,因為每天都有新的模型問世,您可以建立令人驚歎的專案,並將其部署到應用程式託管中。
評論留言