Midjourney API 的對接和使用
閱讀本文大概需要 4 分鐘。
在人工智能繪圖領域,想必大家聽說過 Midjourney 的大名吧。

Midjourney 以其出色的繪圖能力在業(yè)界獨樹一幟。無需過多復雜的操作,只要簡單輸入繪圖指令,這個神奇的工具就能在瞬間為我們呈現(xiàn)出對應的圖像。無論是任何物體還是任何風格,都能在 Midjourney 的繪畫魔法下得以輕松呈現(xiàn)。如今,Midjourney 早已在各個行業(yè)和領域廣泛應用,其影響力愈發(fā)顯著。
然而,在國內(nèi)想要使用 Midjourney 卻面臨著相當大的挑戰(zhàn)。首先,Midjourney 目前駐扎在 Discord 平臺中,這意味著要使用 Midjourney,必須通過特殊的充值途徑獲得訪問權(quán)限。如果沒有訂閱,幾乎無法使用Midjourney,因此單是使用這一工具就成了一個巨大的難題。此外,有人或許會疑問:Midjourney 是否提供對外 API 服務?然而事實是,Midjourney 并未向外界提供任何 API 服務,而且從目前情況看來,這一情況似乎短期也不會改變。
那么,是否有方法能夠與 Midjourney 對接,并將其融入到自己的產(chǎn)品中呢?
答案是肯定的。接下來,我將為大家介紹知數(shù)云平臺所提供的 Midjourney API,通過使用該 API,我們能夠?qū)崿F(xiàn)與 Midjourney 官方完全一致的效果和操作,下文會詳細介紹。
簡介
知數(shù)云平臺是什么呢?簡單來說,它是一個提供多樣數(shù)字化API的服務平臺,其官網(wǎng)鏈接是:https://data.zhishuyun.com[1]。
你可能會疑惑,既然 Midjourney 官方并未向外提供 API,那么知數(shù)云平臺的 API 是如何誕生的呢?簡言之,知數(shù)云的 Midjourney 與 Discord 內(nèi)的Midjourney Bot 進行了接口對接,同時模擬了底層通信協(xié)議,從而能夠在Discord 平臺上實現(xiàn)與 Midjourney 官方完全相同的操作。這涵蓋了文字生成圖片、圖像轉(zhuǎn)換、圖像融合、圖文生成等多個功能。此外,該API在后臺維護了大量 Midjourney 賬號,通過負載均衡控制實現(xiàn)了高度的并發(fā)處理,比官方 Midjourney 單一賬號的并發(fā)能力要更高。
總體來看,無論是在 Discord 上使用 Midjourney 提供的哪一項功能,這個API都能完全還原官方操作的效果和效能。
穩(wěn)定性如何呢?根據(jù)我個人幾個月的觀察和使用經(jīng)驗,可以毫不夸張地說,目前業(yè)界很難找到比知數(shù)云 Midjourney API 更穩(wěn)定且并發(fā)處理能力更高的選擇,而且還能保持 Midjourney 這一價格水平。這樣的選擇寥寥無幾。
下面我們就來了解下這個 API 的申請和使用方法吧。
申請流程
“下文內(nèi)容大多數(shù)來源于知數(shù)云 Midjourney API 官方介紹文檔,文檔鏈接:https://data.zhishuyun.com/documents/0fd3dd40-a16a-4246-8313-748b8e75c29e[2],最新內(nèi)容以官方文檔為準。
”
要使用 Midjourney Imagine API,首先可以到知數(shù)云 Midjourney Imagine API:https://data.zhishuyun.com/documents/58ea7cc1-c685-40c3-a619-f29f9ac5d8f4 頁面點擊「獲取」按鈕:
如果你尚未登錄,會自動跳轉(zhuǎn)到登錄頁面。掃碼關注公眾號即可自動登錄,無需額外注冊步驟。
登錄完了之后會跳回原頁面,此時會提示「您尚未申請該服務,需要申請」。
申請時會校驗實名認證情況,請按照網(wǎng)站提示完成實名認證。實名認證會校驗姓名、手機號、身份證號,需要三者一致才可以通過認證。認證完了之后可以返回頁面,刷新一下頁面確保信息更新,然后重新申請即可通過申請。
基本使用
接下來就可以在界面上填寫對應的內(nèi)容,如圖所示:
在第一次使用該接口時,我們至少需要填寫兩個參數(shù),一個是 action,另一個是 prompt。其中 action 參數(shù)代表了生成圖的操作類型,由于第一次調(diào)用該 API 我們沒有生成過任何內(nèi)容,所以我們需要先輸入文字來生成一副預覽圖,所以這時候 action 應該填寫為 generate。另外一個參數(shù) prompt 就是我們想生成的圖片描述內(nèi)容了,強烈建議用英文描述,畫的圖會更準確效果更好,這里我們填寫了 beautiful dress,代表要畫一條好看的裙子。
依次填寫好圖中所示參數(shù),然后點擊「測試」按鈕即可測試接口。「測試」按鈕下方會顯示 API 返回的結(jié)果。同時您可以注意到右側(cè)有對應的調(diào)用代碼生成,您可以復制代碼到您的 IDE 里面進行對接和開發(fā)。
調(diào)用之后,我們發(fā)現(xiàn)返回結(jié)果如下:
{
"image_url": "https://midjourney.cdn.zhishuyun.com/attachments/1124768570157564029/1142862320582791268/nglover_beautiful_dress_id4899456_02d66331-b4d5-46bd-b5ea-efa6d9447528.png",
"image_id": "1142862320582791268",
"progress": 100,
"actions": [
"upsample1",
"upsample2",
"upsample3",
"upsample4",
"reroll",
"variation1",
"variation2",
"variation3",
"variation4"
],
"task_id": "cf735d83-6e02-4e0a-a265-3e8ed46b8070"
}
返回結(jié)果一共有如下字段:
task_id,生成此圖像任務的 ID,用于唯一標識此次圖像生成任務。
image_id,圖片的唯一標識,在下次需要對圖片進行變換操作時需要傳此參數(shù)。
image_url,圖片的 URL,直接打開即可查看生成的效果,如圖所示:

可以看到,這里生成了一張 2x2 的預覽圖。
actions,可以對生成的圖片進行的進一步操作列表。這里一共列了 9 個,其中 upsample 代表放大,variation 代表變換,reroll 代表重新生成。所以 upsample1 代表的就是對左上角第一張圖片進行放大操作,variation3 就是代表根據(jù)左下角第三張圖片進行變換操作。
到現(xiàn)在為止,第一次 API 調(diào)用就完成了。
“提示:如果您覺得上述生圖速度較慢,想進一步提升用戶體驗,可以考慮采用流式傳輸?shù)哪J交蛘呤褂脴O速 API,具體可參考文檔下方內(nèi)容。
”
圖像放大與變換
下面我們嘗試針對當前生成的照片進行進一步的操作,比如我們覺得右上角第二張的圖片還不錯,但我們想進行一些變換微調(diào),那么就可以進一步將 action 填寫為 variation2,同時將 image_id 傳遞即可,prompt 可以留空:
這時候得到的結(jié)果如下:
{
"image_url": "https://midjourney.cdn.zhishuyun.com/attachments/1124768570157564029/1142864001001345245/handerson6243_beautiful_dress_id4899456_aab4a0bf-7d99-4b7f-818c-c4dc690300ea.png",
"image_id": "1142864001001345245",
"progress": 100,
"actions": [
"upsample1",
"upsample2",
"upsample3",
"upsample4",
"reroll",
"variation1",
"variation2",
"variation3",
"variation4"
],
"task_id": "b6f464b6-0cac-43e7-ae4e-12658679b7f3"
}
打開 image_url,新生成的圖片如下所示:

可以看到,針對上一張右上角的圖片,我們再次得到了四張類似的照片。
這時候我們可以挑選其中一張進行精細化地放大操作,比如選第四張,那就可以 action 傳入 upsample4,通過 image_id 再次傳入當前圖像的 ID 即可。
“注意:
”upsample操作相比variation來說,Midjourney 的耗時會更短一些。
返回結(jié)果如下:
{
"image_url": "https://midjourney.cdn.zhishuyun.com/attachments/1124768570157564029/1142864651860840458/ruthgarcia3808_beautiful_dress_id4899456_096f6a64-7412-4cb5-8f50-4afbfc456d55.png",
"image_id": "1142864651860840458",
"progress": 100,
"actions": [
"high_variation",
"low_variation",
"zoom_out_2x",
"zoom_out_1_5x",
"pan_left",
"pan_right",
"pan_up",
"pan_down"
],
"task_id": "9f5c34e3-c8af-415c-9377-fb46cd47ad45"
}
其中 image_url 如圖所示:
這樣我們就成功得到了一張獨立的連衣裙的照片。
同時注意到 actions 里面又包含了幾個可進行的操作,介紹如下:
high_variation:對畫面進行高變換(具體含義請參考 Midjourney 官方)。
low_variation:對畫面進行低變換(具體含義請參考 Midjourney 官方)。
zoom_out_2x:對畫面進行縮小兩倍操作(周圍區(qū)域填充)。
zoom_out_1_5x:對畫面進行縮小 1.5 倍操作(周圍區(qū)域填充)。
pan_left:對畫面進行左移和填充操作。
pan_right:對畫面進行右移和填充操作。
pan_top:對畫面進行上移和填充操作。
pan_bottom:對畫面進行下移和填充操作。
可以繼續(xù)按照上述流程傳入對應的變換指令進行連續(xù)生圖操作,可以實現(xiàn)無限次連續(xù)操作,這里不再一一贅述。
圖像改寫(墊圖)
該 API 也支持圖像改寫,俗稱墊圖,我們可以輸入一張圖片 URL 以及需要改寫的描述文字,該 API 就可以返回改寫后的圖片。
“注意:輸入的圖片 URL 需要是一張純圖片,不能是一個網(wǎng)頁里面展示一張圖片,否則無法進行圖像改寫。建議使用圖床(如阿里云 OSS、騰訊云 COS、七牛云、又拍云等)來上傳獲取圖片的 URL。
”
假設這里我們有一張圖片,URL 是 https://zhishuyun-1256437459.cos.ap-beijing.myqcloud.com/20230504-222359.png[5],是一張小女孩寫字的圖片:

現(xiàn)在我們想把它轉(zhuǎn)化為卡通風格,可以直接在 prompt 字段將 URL 和要調(diào)整的文字一并輸入即可,二者用空格分隔,比如:
https://zhishuyun-1256437459.cos.ap-beijing.myqcloud.com/20230504-222359.png transfer to cartoon style
樣例調(diào)用如下:
輸出結(jié)果如下:
{
"task_id": "9297d5ab-4014-44d4-91c8-a6d8927a0756",
"image_id": "1103689414850387968",
"image_url": "https://midjourney.cdn.zhishuyun.com/attachments/1100813695770165341/1103689414850387968/Azyern_Zieca_ignore9297d5ab-4014-44d4-91c8-a6d8927a0756_ec5cda5c-8784-4707-be17-a168786e0c8a.png",
"actions": [
"upsample1",
"upsample2",
"upsample3",
"upsample4",
"variation1",
"variation2",
"variation3",
"variation4"
]
}
這時候,我們可以看到就得到了類似的卡通風格的圖片了:

異步回調(diào)
由于 Midjourney 生成圖片需要等待一段時間,所以本 API 也相應設計為了長等待模式。但在部分場景下,長等待可能會帶來一些額外的資源開銷,因此本 API 也提供了異步 Webhook 回調(diào)的方式,當圖片生成成功或失敗時,其結(jié)果都會通過 HTTP 請求的方式發(fā)送到指定的 Webhook 回調(diào) URL。回調(diào) URL 接收到結(jié)果之后可以進行進一步的處理。
下面演示具體的調(diào)用流程。
首先,Webhook 回調(diào)是一個可以接收 HTTP 請求的服務,開發(fā)者應該替換為自己搭建的 HTTP 服務器的 URL。此處為了方便演示,使用一個公開的 Webhook 樣例網(wǎng)站 https://webhook.site/[6],打開該網(wǎng)站即可得到一個 Webhook URL,如圖所示:
將此 URL 復制下來,就可以作為 Webhook 來使用,此處的樣例為 https://webhook.site/c62713a6-0487-45bd-9ad2-08a91d7ed12d[7]。
接下來,我們可以設置字段 callback_url 為上述 Webhook URL,同時填入 prompt,如圖所示:
點擊測試之后會立即得到一個 task_id 的響應,用于標識當前生成任務的 ID,如圖所示:
稍等片刻,等圖片生成結(jié)束,可以發(fā)發(fā)現(xiàn) Webhook URL 收到了一個 HTTP 請求,如圖所示:
其結(jié)果就是當前任務的結(jié)果,內(nèi)容如下:
{
"success": true,
"task_id": "8aad0fe0-2300-4702-94dc-39a5d3e2f2f3",
"actions": [
"upsample1",
"upsample2",
"upsample3",
"upsample4",
"variation1",
"variation2",
"variation3",
"variation4"
],
"image_id": "1103693480024363198",
"image_url": "https://midjourney.cdn.zhishuyun.com/attachments/1100813695770165341/1103693480024363198/Azyern_Zieca_ignore8aad0fe0-2300-4702-94dc-39a5d3e2f2f3_a_beaut_b3d5720a-b917-4a2d-b6e7-ae641ee7ca4f.png"
}
其中 success 字段標識了該任務是否執(zhí)行成功,如果執(zhí)行成功,還會有同樣的 actions, image_id, image_url 字段,和上文介紹的返回結(jié)果是一樣的,另外還有 task_id 用于標識任務,以實現(xiàn) Webhook 結(jié)果和最初 API 請求的關聯(lián)。
如果圖片生成失敗,Webhook URL 則會收到類似如下內(nèi)容:
{
"success": false,
"task_id": "7ba0feaf-d20b-4c22-a35a-31ec30fc7715",
"code": "bad_request",
"detail": "Unrecognized argument(s): `-c`, `x`"
}
這里的 success 字段會是 false,同時還會有 code 和 detail 字段描述了任務錯誤的詳情信息,Webhook 服務器根據(jù)對應的結(jié)果進行處理即可。
流式輸出
Midjourney 官方在生成圖片的時候是有進度的,在最開始是一張模糊的照片,然后經(jīng)過幾次迭代之后,圖片逐漸變得清晰,最后得到完整的圖片。
所以,一張圖片的生成過程大約可以分為「發(fā)送命令」->「開始生圖(多次迭代逐漸清晰)」->「生圖完畢」的階段。
在沒開啟流式輸出的情況下,本 API 從發(fā)起請求到返回結(jié)果,實際上是從上述「發(fā)送命令」->「生圖完畢」的全過程,中間生圖的過程也全被包含在里面,由于 Midjourney 本身生成圖片速度較慢,整個過程大約需要等待一分鐘或更久。
所以為了更好的用戶體驗,本 API 支持流式輸出,即當「開始生圖」的時候就開始返回結(jié)果,每當繪制進度有變化,就會流式將結(jié)果輸出,直至生圖結(jié)束。
如果想流式返回響應,可以更改請求頭里面的 accept 參數(shù),修改為 application/x-ndjson,不過調(diào)用代碼需要有對應的更改才能支持流式響應。
Python 樣例代碼:
import requests
url = 'https://api.zhishuyun.com/midjourney/imagine?token={token}'
headers = {
'content-type': 'application/json',
'accept': 'application/x-ndjson'
}
body = {
"prompt": "a beautiful cat",
"action": "generate"
}
r = requests.post(url, headers=headers, json=body, stream=True)
for line in r.iter_lines():
print(line.decode())
運行結(jié)果:
{"image_id":"1112780200447578272","image_url":"https://midjourney.cdn.zhishuyun.com/attachments/1111955518269948007/1112780200447578272/grid_0.webp","actions":[],"progress":0}
{"image_id":"1112780227496640635","image_url":"https://midjourney.cdn.zhishuyun.com/attachments/1111955518269948007/1112780227496640635/grid_0.webp","actions":[],"progress":15}
{"image_id":"1112780238934523994","image_url":"https://midjourney.cdn.zhishuyun.com/attachments/1111955518269948007/1112780238934523994/grid_0.webp","actions":[],"progress":31}
{"image_id":"1112780254398918716","image_url":"https://midjourney.cdn.zhishuyun.com/attachments/1111955518269948007/1112780254398918716/grid_0.webp","actions":[],"progress":46}
{"image_id":"1112780265933262858","image_url":"https://midjourney.cdn.zhishuyun.com/attachments/1111955518269948007/1112780265933262858/grid_0.webp","actions":[],"progress":62}
{"image_id":"1112780280965648394","image_url":"https://midjourney.cdn.zhishuyun.com/attachments/1111955518269948007/1112780280965648394/grid_0.webp","actions":[],"progress":78}
{"image_id":"1112780292621598860","image_url":"https://midjourney.cdn.zhishuyun.com/attachments/1111955518269948007/1112780292621598860/grid_0.webp","actions":[],"progress":93}
{"image_id":"1112780319758766080","image_url":"https://midjourney.cdn.zhishuyun.com/attachments/1111955518269948007/1112780319758766080/dawn97_ignore81c5c24e-ea94-4ae2-aee4-252a98a347ed_a_beautiful_c_e20c3bc8-8827-4c99-9cf5-7d56c2e9d47f.png","actions":["upsample1","upsample2","upsample3","upsample4","variation1","variation2","variation3","variation4"],"progress":100}
可以看到,啟用流式輸出之后,返回結(jié)果就是逐行的 JSON 了。在這里我們用 Python 里面的 iter_lines 方法自動獲取了下一行的內(nèi)容并打印出來。
如果要手動進行處理逐行 JSON 結(jié)果的話可以使用 \r\n 來進行分割。
例如在瀏覽器環(huán)境中,用 JavaScript 的 axios 庫來實現(xiàn)手動處理,代碼可改寫如下:
axios({
url: 'https://api.zhishuyun.com/midjourney/imagine?token={token}',
data: {
prompt: 'a beautiful cat',
action: 'generate'
},
headers: {
'accept': 'application/x-ndjson',
'content-type': 'application/json'
},
responseType: 'stream',
method: 'POST',
onDownloadProgress: progressEvent => {
const response = progressEvent.target.response;
const lines = response.split('\r\n').filter(line => !!line)
const lastLine = lines[lines.length - 1]
console.log(lastLine)
}
}).then(({ data }) => Promise.resolve(data));
但注意在 Node.js 環(huán)境中,實現(xiàn)稍有不同,代碼可寫為如下:
const axios = require('axios');
const url = 'https://api.zhishuyun.com/midjourney/imagine?token={token}';
const headers = {
'Content-Type': 'application/json',
'Accept': 'application/x-ndjson'
};
const body = {
prompt: 'a beautiful cat',
action: 'generate'
};
axios.post(url, body, { headers: headers, responseType: 'stream' })
.then(response => {
console.log(response.status);
response.data.on('data', chunk => {
console.log(chunk.toString());
});
})
.catch(error => {
console.error(error);
});
Java 樣例代碼:
import okhttp3.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) {
String url = "https://api.zhishuyun.com/midjourney/imagine?token={token}";
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\"prompt\": \"a beautiful cat\"}");
Request request = new Request.Builder()
.url(url)
.post(body)
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/x-ndjson")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
try (BufferedReader br = new BufferedReader(
new InputStreamReader(response.body().byteStream(), "UTF-8"))) {
String responseLine;
while ((responseLine = br.readLine()) != null) {
System.out.println(responseLine);
}
}
}
});
}
}
運行結(jié)果都是類似的。
另外注意到,流式輸出的結(jié)果多了一個字段叫做 progress,這個代表繪制進度,范圍是 0-100,如果需要,您也可以在頁面展示這個信息。
“注意:當繪制未完全完成的時候,
”actions字段是空,即無法對中間過程的圖片做進一步的處理操作。繪制完畢之后,繪制過程中產(chǎn)生的image_url會被銷毀。另外異步回調(diào)可以和流式輸出一起使用。
好了,通過以上內(nèi)容介紹,我們就了解了知數(shù)云 Midjourney API 的使用方法,有了這個 API,我們可以包裝自己的產(chǎn)品,實現(xiàn)和官方 Midjourney 一模一樣的對接。
套餐介紹
到了最后,大家可能好奇,這個價格套餐式怎樣的情況呢?
知數(shù)云對上文介紹的 API 提供了三種套餐,分別是快速、慢速、極速模式,介紹如下:
- 快速:背后的 Midjourney 賬號均是 Fast 模式,能夠以快速模式出圖,正常情況下繪制完整圖片時間在 1 分鐘左右,開啟流式模式會更快。
- 慢速:背后的 Midjourney 賬號均是 Relax 模式,生成速度無任何保證,快的話可能 1 分鐘,慢的話可能甚至 10 分鐘,適合對速度要求較低的用戶。
- 極速:背后的 Midjourney 賬號軍事 Turbo 模式,生成速度比快速模式更快,正常情況下繪制完整圖片時間在 30 秒左右,開啟流式模式會更快。適合對速度要求極高的用戶。
價格怎么樣呢?由于價格可能會動態(tài)變化,大家可以直接參考知數(shù)云的官方網(wǎng)站了解:https://data.zhishuyun.com/services/d87e5e99-b797-4ade-9e73-b896896b0461[8]。但總的來說,能夠以這個價格做到知數(shù)云 Midjourney API 這樣的穩(wěn)定性和并發(fā)的,業(yè)界寥寥無幾,歡迎選購和評測。
