在人工智能绘图范畴,想必咱们听说过 Midjourney 的大名吧!

Midjourney 以其出色的绘图才能在业界独树一帜。无需过多复杂的操作,只要简略输入绘图指令,这个奇特的东西就能在瞬间为咱们呈现出对应的图画。无论是任何物体还是任何风格,都能在Midjourney的绘画魔法下得以轻松呈现。现在,Midjourney 早已在各个职业和范畴广泛应用,其影响力益发显著。

然而,在国内想要运用 Midjourney 却面临着相当大的挑战。首要,Midjourney 现在驻扎在 Discord 渠道中,这意味着要运用 Midjourney,必须通过特殊的充值途径获得访问权限。假如没有订阅,几乎无法运用 Midjourney,因此单是运用这一东西就成了一个巨大的难题。此外,有人或许会疑问:Midjourney 是否供给对外API服务?然而事实是,Midjourney 并未向外界供给任何API服务,并且从现在状况看来,这一状况好像也不会改变。

那么,是否有办法能够与 Midjourney 对接,并将其融入到自己的产品中呢?

答案是必定的。接下来,我将为咱们介绍知数云渠道所供给的 Midjourney API,通过运用该 API,咱们能够完结与 Midjourney 官方彻底一致的作用和操作,下文会详细介绍。

简介

知数云渠道是什么呢?简略来说,它是一个供给多样数字化 API 的服务渠道,其官网链接是:data.zhishuyun.com。

你或许会疑问,已然 Midjourney 官方并未向外供给 API,那么知数云渠道的API是怎么诞生的呢?简言之,知数云的 Midjourney 与 Discord 内的 Midjourney Bot 进行了接口对接,一同模拟了底层通信协议,从而能够在 Discord 渠道上完结与 Midjourney 官方彻底相同的操作。这涵盖了文字生成图片、图画转换、图画融合、图文生成等多个功能。此外,该 API 在后台维护了很多 Midjourney 账号,通过负载均衡控制完结了高度的并发处理,比官方 Midjourney 单一账号的并发才能要更高。

整体来看,无论是在 Discord 上运用 Midjourney 供给的哪一项功能,这个 API 都能彻底还原官方操作的作用和效能。

稳定性怎么呢?依据我个人几个月的调查和运用经验,能够毫不夸张地说,现在业界很难找到比知数云 Midjourney API 更稳定且并发处理才能更高的挑选,并且还能保持 Midjourney 这一价格水平。这样的挑选寥寥无几。

下面咱们就来了解下这个 API 的恳求和运用办法吧。

恳求流程

下文内容大多数来源于知数云 Midjourney API 官方介绍文档,文档链接:data.zhishuyun.com/documents/0…,最新内容以官方文档为准。

要运用 Midjourney Imagine API,首要能够到 Midjourney Imagine API 页面点击「获取」按钮:

Midjourney API 申请及使用

假如你没有登录,会主动跳转到登录页面。扫码重视公众号即可主动登录,无需额定注册步骤。

登录完了之后会跳回原页面 Midjourney Imagine API ,此时会提示「您没有恳求该服务,需求恳求」。

恳求时会校验实名认证状况,请依照网站提示完结实名认证。实名认证会校验姓名、手机号、身份证号,需求三者一致才能够通过认证。认证完了之后能够回来页面,刷新一下页面保证信息更新,然后从头恳求即可通过恳求。

根本运用

接下来就能够在界面上填写对应的内容,如图所示:

Midjourney API 申请及使用

在第一次运用该接口时,咱们至少需求填写两个参数,一个是 action,另一个是 prompt。其间 action 参数代表了生成图的操作类型,因为第一次调用该 API 咱们没有生成过任何内容,所以咱们需求先输入文字来生成一副预览图,所以这时分 action 应该填写为 generate。别的一个参数 prompt 便是咱们想生成的图片描述内容了,强烈建议用英文描述,画的图会更精确作用更好,这儿咱们填写了 beautiful dress,代表要画一条美观的裙子。

顺次填写好图中所示参数,然后点击「测验」按钮即可测验接口。「测验」按钮下方会显示 API 回来的成果。一同您能够留意到右侧有对应的调用代码生成,您能够仿制代码到您的 IDE 里边进行对接和开发。

调用之后,咱们发现回来成果如下:

{
  "image_url": "https://www.6hu.cc/files/2023/10/1698135346-74a669e8fde671d.png",
  "image_id": "1142862320582791268",
  "progress": 100,
  "actions": [
    "upsample1",
    "upsample2",
    "upsample3",
    "upsample4",
    "reroll",
    "variation1",
    "variation2",
    "variation3",
    "variation4"
  ],
  "task_id": "cf735d83-6e02-4e0a-a265-3e8ed46b8070"
}

回来成果总共有如下字段:

task_id,生成此图画使命的 ID,用于仅有标识此次图画生成使命。

image_id,图片的仅有标识,在下次需求对图片进行改换操作时需求传此参数。

image_url,图片的 URL,直接翻开即可检查生成的作用,如图所示:

Midjourney API 申请及使用

能够看到,这儿生成了一张 2×2 的预览图。

actions,能够对生成的图片进行的进一步操作列表。这儿总共列了 9 个,其间 upsample 代表扩大,variation 代表改换,reroll 代表从头生成。所以 upsample1 代表的便是对左上角第一张图片进行扩大操作,variation3 便是代表依据左下角第三张图片进行改换操作。

到现在为止,第一次 API 调用就完结了。

提示:假如您觉得上述生图速度较慢,想进一步提高用户体验,能够考虑采用流式传输的形式或许运用极速 API,详细可参阅文档下方内容。

图画扩大与改换

下面咱们尝试针对当时生成的相片进行进一步的操作,比方咱们觉得右上角第二张的图片还不错,但咱们想进行一些改换微调,那么就能够进一步将 action 填写为 variation2,一同将 image_id 传递即可,prompt 能够留空:

Midjourney API 申请及使用

这时分得到的成果如下:

{
  "image_url": "https://www.6hu.cc/files/2023/10/1698135356-8ad76a062cb5879.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,新生成的图片如下所示:

Midjourney API 申请及使用

能够看到,针对上一张右上角的图片,咱们再次得到了四张相似的相片。

这时分咱们能够挑选其间一张进行精细化地扩大操作,比方选第四张,那就能够 action 传入 upsample4,通过 image_id 再次传入当时图画的 ID 即可。

Midjourney API 申请及使用

留意: upsample 操作比较 variation 来说,Midjourney 的耗时会更短一些。

回来成果如下:

{
  "image_url": "https://www.6hu.cc/files/2023/10/1698135364-68e615ad0a9d8f7.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 如图所示:

Midjourney API 申请及使用

这样咱们就成功得到了一张独立的连衣裙的相片。

一同留意到 actions 里边又包含了几个可进行的操作,介绍如下:

high_variation:对画面进行高改换(详细意义请参阅 Midjourney 官方)。

low_variation:对画面进行低改换(详细意义请参阅 Midjourney 官方)。

zoom_out_2x:对画面进行缩小两倍操作(周围区域填充)。

zoom_out_1_5x:对画面进行缩小 1.5 倍操作(周围区域填充)。

pan_left:对画面进行左移和填充操作。

pan_right:对画面进行右移和填充操作。

pan_top:对画面进行上移和填充操作。

pan_bottom:对画面进行下移和填充操作。

能够继续依照上述流程传入对应的改换指令进行连续生图操作,能够完结无限次连续操作,这儿不再逐个赘述。

图画改写(垫图)

该 API 也支撑图画改写,俗称垫图,咱们能够输入一张图片 URL 以及需求改写的描述文字,该 API 就能够回来改写后的图片。

留意:输入的图片 URL 需求是一张纯图片,不能是一个网页里边展现一张图片,否则无法进行图画改写。建议运用图床(如阿里云 OSS、腾讯云 COS、七牛云、又拍云等)来上传获取图片的 URL。

假设这儿咱们有一张图片,URL 是 zhishuyun-1256437459.cos.ap-beijing.myqcloud.com/20230504-22…,是一张小女孩写字的图片:

Midjourney API 申请及使用

现在咱们想把它转化为卡通风格,能够直接在 prompt 字段将 URL 和要调整的文字一同输入即可,二者用空格分隔,比方:

https://zhishuyun-1256437459.cos.ap-beijing.myqcloud.com/20230504-222359.png transfer to cartoon style

样例调用如下:

Midjourney API 申请及使用

输出成果如下:

{
  "task_id": "9297d5ab-4014-44d4-91c8-a6d8927a0756",
  "image_id": "1103689414850387968",
  "image_url": "https://www.6hu.cc/files/2023/10/1698135374-c1117ba0ab31a94.png",
  "actions": [
    "upsample1",
    "upsample2",
    "upsample3",
    "upsample4",
    "variation1",
    "variation2",
    "variation3",
    "variation4"
  ]
}

这时分,咱们能够看到就得到了相似的卡通风格的图片了:

Midjourney API 申请及使用

异步回调

因为 Midjourney 生成图片需求等候一段时刻,所以本 API 也相应设计为了长等候形式。但在部分场景下,长等候或许会带来一些额定的资源开销,因此本 API 也供给了异步 Webhook 回调的方法,当图片生成成功或失利时,其成果都会通过 HTTP 恳求的方法发送到指定的 Webhook 回调 URL。回调 URL 接收到成果之后能够进行进一步的处理。

下面演示详细的调用流程。

首要,Webhook 回调是一个能够接收 HTTP 恳求的服务,开发者应该替换为自己搭建的 HTTP 服务器的 URL。此处为了便利演示,运用一个公开的 Webhook 样例网站 webhook.site/,翻开该网站即可得到一个 Webhook URL,如图所示:

Midjourney API 申请及使用

将此 URL 仿制下来,就能够作为 Webhook 来运用,此处的样例为 webhook.site/c62713a6-04…。

接下来,咱们能够设置字段 callback_url 为上述 Webhook URL,一同填入 prompt,如图所示:

Midjourney API 申请及使用

点击测验之后会立即得到一个 task_id 的呼应,用于标识当时生成使命的 ID,如图所示:

Midjourney API 申请及使用

稍等片刻,等图片生成结束,能够发发现 Webhook URL 收到了一个 HTTP 恳求,如图所示:

Midjourney API 申请及使用

其成果便是当时使命的成果,内容如下:

{
  "success": true,
  "task_id": "8aad0fe0-2300-4702-94dc-39a5d3e2f2f3",
  "actions": [
    "upsample1",
    "upsample2",
    "upsample3",
    "upsample4",
    "variation1",
    "variation2",
    "variation3",
    "variation4"
  ],
  "image_id": "1103693480024363198",
  "image_url": "https://www.6hu.cc/files/2023/10/1698135383-3fde924d82c5dd3.png"
}

其间 success 字段标识了该使命是否履行成功,假如履行成功,还会有同样的 actions, image_id, image_url 字段,和上文介绍的回来成果是相同的,别的还有 task_id 用于标识使命,以完结 Webhook 成果和最初 API 恳求的相关。

假如图片生成失利,Webhook URL 则会收到相似如下内容:

{
  "success": false,
  "task_id": "7ba0feaf-d20b-4c22-a35a-31ec30fc7715",
  "code": "bad_request",
  "detail": "Unrecognized argument(s): `-c`, `x`"
}

这儿的 success 字段会是 false,一同还会有 codedetail 字段描述了使命过错的概况信息,Webhook 服务器依据对应的成果进行处理即可。

流式输出

Midjourney 官方在生成图片的时分是有进展的,在最开端是一张含糊的相片,然后通过几回迭代之后,图片逐步变得清晰,最终得到完整的图片。

所以,一张图片的生成进程大约能够分为「发送指令」->「开端生图(多次迭代逐步清晰)」->「生图结束」的阶段。

在没敞开流式输出的状况下,本 API 从建议恳求到回来成果,实际上是从上述「发送指令」->「生图结束」的全进程,中心生图的进程也全被包含在里边,因为 Midjourney 自身生成图片速度较慢,整个进程大约需求等候一分钟或更久。

所以为了更好的用户体验,本 API 支撑流式输出,即当「开端生图」的时分就开端回来成果,每逢制作进展有变化,就会流式将成果输出,直至生图结束。

假如想流式回来呼应,能够更改恳求头里边的 accept 参数,修改为 application/x-ndjson,不过调用代码需求有对应的更改才能支撑流式呼应。

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())

运转成果:

{"image_id":"1112780200447578272","image_url":"https://midjourney.cdn.zhishuyun.com/attachments/1111955518269948007/1112780200447578272/grid_0.webp","actions":[],"progress":0}
{"image_id":"1112780227496640635","image_url":"","actions":[],"progress":15}
{"image_id":"1112780238934523994","image_url":"","actions":[],"progress":31}
{"image_id":"1112780254398918716","image_url":"","actions":[],"progress":46}
{"image_id":"1112780265933262858","image_url":"","actions":[],"progress":62}
{"image_id":"1112780280965648394","image_url":"","actions":[],"progress":78}
{"image_id":"1112780292621598860","image_url":"","actions":[],"progress":93}
{"image_id":"1112780319758766080","image_url":"https://www.6hu.cc/files/2023/10/1698135392-ce1b24aa12ea4c3.png","actions":["upsample1","upsample2","upsample3","upsample4","variation1","variation2","variation3","variation4"],"progress":100}

能够看到,启用流式输出之后,回来成果便是逐行的 JSON 了。在这儿咱们用 Python 里边的 iter_lines 办法主动获取了下一行的内容并打印出来。

假如要手动进行处理逐行 JSON 成果的话能够运用 \r\n 来进行切割。

例如在浏览器环境中,用 JavaScript 的 axios 库来完结手动处理,代码可改写如下:

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 环境中,完结稍有不同,代码可写为如下:

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);
                    }
                }
            }
        });
    }
}

运转成果都是相似的。

别的留意到,流式输出的成果多了一个字段叫做 progress,这个代表制作进展,范围是 0-100,假如需求,您也能够在页面展现这个信息。

留意:当制作未彻底完结的时分,actions 字段是空,即无法对中心进程的图片做进一步的处理操作。制作结束之后,制作进程中发生的 image_url 会被毁掉。别的异步回调能够和流式输出一同运用。

好了,通过以上内容介绍,咱们就了解了知数云 Midjourney API 的运用办法,有了这个 API,咱们能够包装自己的产品,完结和官方 Midjourney 一模相同的对接。

套餐介绍

到了最终,咱们或许好奇,这个价格套餐式怎样的状况呢?

知数云对上文介绍的 API 供给了三种套餐,分别是快速、慢速、极速形式,介绍如下:

  • 快速:背面的 Midjourney 账号均是 Fast 形式,能够以快速形式出图,正常状况下制作完整图片时刻在 1 分钟左右,敞开流式形式会更快。
  • 慢速:背面的 Midjourney 账号均是 Relax 形式,生成速度无任何保证,快的话或许 1 分钟,慢的话或许甚至 10 分钟,合适对速度要求较低的用户。
  • 极速:背面的 Midjourney 账号军事 Turbo 形式,生成速度比快速形式更快,正常状况下制作完整图片时刻在 30 秒左右,敞开流式形式会更快。合适对速度要求极高的用户。

价格怎么样呢?因为价格或许会动态变化,咱们能够直接参阅知数云的官方网站了解:data.zhishuyun.com/services/d8…。但总的来说,能够以这个价格做到知数云 Midjourney API 这样的稳定性和并发的,业界寥寥无几,欢迎选购和评测。

谢谢!