基於OpenAI API構建圖片生成器

語言: CN / TW / HK
ead>

一、簡介

最近,圍繞ChatGPT和OpenAI的話題是層出不窮,國內外的技術工作者都掀起了一股學習OpenAI的技術浪潮,甚至有很多的媒體預測OpenAI將會帶來行業的革命,而國外一些大的企業也將OpenAI視為重要的競爭對手,比如Google和微軟。

事實上,OpenAI 可以應用於任何涉及理解或生成自然語言或代碼的任務。他們提供一系列適用於不同的任務模型,並且還能夠根據自己的需求微調自定義模型。這些模型可用於從內容生成到語義搜索和分類的所有領域,例如文本補充、代碼編寫、SQL翻譯、JS助手聊天機器人等。 

image.png

但是,對於OpenAI的應用,國內外都還處於起步階段。對於OpenAI在商業方面的應用,資料也比較少,那如果利用OpenAI Api進行商業化開發,就是本文需要給大家分享的。

二、構建圖像生成器

在正式應用之前,我們需要先申請一個OpenAI賬號,註冊流程可以參考:超詳細的ChatGPT註冊教程

2.1 創建Node.js項目

首先,我們創建一個Node.js項目,然後在項目中安裝Express、nodemon、openai等插件。然後,打開package.json文件,創建start和dev命令腳本,如下。

"devDependencies": { "body-parser": "^1.20.1", "dotenv": "^16.0.3", "express": "^4.18.2", "nodemon": "^2.0.20" }, "dependencies": { "openai": "^3.1.0" }

接着,創建index.js文件作為應用的入口文件,分別引入express和detenv。

``` const express = require('express') const dotenv=require('dotenv').config() const port=process.env.PORT || 5000 const index = express()

index.listen(port, () => console.log(啟動服務器)) ```

然後,在package.json文件中添加啟動腳本,如下。

"scripts": { "start": "node index.js", "dev": "nodemon index.js" },

2.2 申請OpenAI Key

接下來,打開OpenAI官網,點擊右上角的頭像按鈕,獲取OpenAI的Key,如下圖。

image.png

2.3 創建Route和Controller

接下來,我們創建業務路由,並添加業務代碼。首先,創建一個openai_route.js路由,添加如下代碼。

``` const express = require('express') const router = express.Router()

router.post('/createImage',(req,res)=>{ res.status(200).json({ success:true }) })

module.exports=router; ```

接着,在index.js文件中引入openai_route.js,如下。

``` const openai=require('./routers/openai_route') index.use('/openai',openai)

...//省略其他代碼 ```

重新啟動Node項目,然後使用Postman工具測試圖像構建接口,測試地址為localhost:5000/openai/createImageVariation,請求類型POST,如下圖所示,請求成功接口會返回成功的提示。   image.png

接下來,我們新建openai_controller.js文件,將上文生成圖像的函數定義到此文件,如下。

``` const createImage = async (req,res)=>{ res.status(200).json({ success:true }) }

module.exports= {createImage}; ```

然後,在openai_routes.js文件中引入openai_controller.js,此時openai_controller.js文件中的內容改造後如下。

``` const express = require('express'); const {createImage}=require('../controller/openai_controller') const router = express.Router();

router.post('/createImage',createImage)

module.exports=router; ```

最後,我們重啟Node項目,然後使用Postman工具測試上面的接口,如果能夠正常返回數據,則説明沒有任何問題。

image.png

2.4 OpenAI使用

2.4.1 基本使用

接下來,我們在openai_controller.js文件中引入openai的API接口creatImage, 具體使用方法可以查看 OpenAI API 的Image generation。根據creatImage函數的入參要求,需要傳入prompt、n和size三個參數,如下所示。

const response = await openai.createImage({ prompt: "a white siamese cat", n: 1, size: "1024x1024", }); image_url = response.data.data[0].url;

下面是我們使用openai的createImage方法生成圖片的方法,代碼如下:

``` const {Configuration, OpenAIApi} = require('openai') const configuration = new Configuration({ apiKey: process.env.OPENAI_API_KEY }) const openai = new OpenAIApi(configuration) const createImage = async (req, res) => { try { const response = await openai.createImage({ prompt: "a white siamese cat", n: 1, size: "1024x1024", }) const imageUrl = response.data.data[0].url res.status(200).json({ success: true, data: imageUrl }) } catch (error) { console.log(error.response) res.status(400).json({ success:false, error:'the image create failed' }) } }

module.exports={createImage} ```

接下來,我們重啟Node.js項目,並使用Postman測試接口,如果成功返回圖片數據,則説明接口調用成功。

image.png  

2.4.2 設置body

接下來,我們看一下如何在請求過程中添加body部分。首先,我們需要在index.js文件中開啟 body parser。

``` const express = require('express') const index = express() ... //省略其他代碼

//開啟Body Parser index.use(express.urlencoded({extended: false})) index.use(express.json()) ```

然後,在openai_controller.js中對獲取到body解析裏面的數據,如下:

``` const {Configuration, OpenAIApi} = require('openai')

const configuration = new Configuration({ apiKey: process.env.OPENAI_API_KEY })

const openai = new OpenAIApi(configuration)

const createImage = async (req, res) => { //獲取Body數據 const {prompt,size}=req.body const imageSize=size==='small'?'256x256':size==='medium'?'512x512':'1024x1024'

try {
    const response = await openai.createImage({
        prompt: prompt,
        n: 1,
        size: imageSize,
    })


    const imageUrl = response.data.data[0].url


    res.status(200).json({
        success: true,
        data: imageUrl
    })
} catch (error) {
    console.log(error.response)


    res.status(400).json({
        success:false,
        error:'the image create failed'
    })
}

}

module.exports={createImage} ```

現在,我們重啟Node.js項目,然後使用Postman測試接口。這次測試我們給body中增加了參數,我們將prompt設置為“man on the moon”(月球上的人),size選擇為“medium”,返回的s數據如下圖。

image.png  

2.4.3 設置靜態文件

接下來,我們新建一個public文件夾專門放置靜態資源文件,然後在index.js文件中引入靜態文件資源。首先,我們新建index.html文件,內容如下。

```

<script src="js/main.js" defer></script>
<title>OpenAI Image Genrator</title>


Describe An Image

```

代碼中涉及的css文件需要存放在public文件夾下 ,css樣式的源碼可查看github地址。然後,在index.js文件中設置靜態文件。

``` const path = require('path')

... //省略其他代碼 index.use(express.static(path.join(__dirname, 'public'))); ```

2.4.4 表單事件監聽

為了能夠讓項目看起來更完整,我們還需要為上一步創建的表單增加事件監聽。首先,在public文件夾下新建一個js文件夾,然後再文件夾下新建main.js文件。

``` function onSubmit(e) { e.preventDefault();

document.querySelector('.msg').textContent = ''; document.querySelector('#image').src = '';

const prompt = document.querySelector('#prompt').value; const size = document.querySelector('#size').value;

if (prompt === '') { alert('Please add some text'); return; } console.log(prompt, size); }

document.querySelector('#image-form').addEventListener('submit', onSubmit); ```

2.4.5 新增獲取圖像函數

接下來,我們在main.js文件中新增一個獲取圖像函數用於去調用前面定義的/openai/createImage接口,然後將獲取到的圖像設置DOM中顯示。

``` function onSubmit(e) { e.preventDefault();

document.querySelector('.msg').textContent = ''; document.querySelector('#image').src = '';

const prompt = document.querySelector('#prompt').value; const size = document.querySelector('#size').value;

if (prompt === '') { alert('Please add some text'); return; }

createImageRequest(prompt, size); }

async function createImageRequest(prompt, size) { try { showSpinner();

const response = await fetch('/openai/createImage', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    prompt,
    size,
  }),
});


if (!response.ok) {
  removeSpinner();
  throw new Error('That image could not be generated');
}


const data = await response.json();
const imageUrl = data.data;


document.querySelector('#image').src = imageUrl;


removeSpinner();

} catch (error) { document.querySelector('.msg').textContent = error; } }

function showSpinner() { document.querySelector('.spinner').classList.add('show'); }

function removeSpinner() { document.querySelector('.spinner').classList.remove('show'); }

document.querySelector('#image-form').addEventListener('submit', onSubmit); ```

最後,我們啟動項目,然後在瀏覽器中輸入地址:http://localhost:5000/。啟動成功後,我們在頁面中的輸入框中輸入【brad traversy person web development】,大小選擇【Medium】,點擊提交按鈕即可獲得圖片。

image.png

image.png

參考

項目源碼:https://github.com/bradtraversy/nodejs-openai-image
openai官方文檔:https://platform.openai.com/docs/introduction
更多示例:https://traversymedia.com