首先来一波感谢:
感谢laf提供赞助,目前可以免费使用Midjourney进行开发和测试。
感谢白夜、米开朗基杨@sealos.io的耐心解答,让我对laf有了更多的使用与了解。
什么是laf?来了解下。
文末有【示例】
开始
废话不多说,进入正题。
laf在做一个活动,可以使用快速上手Midjourney《人人都能接入 Midjourney》。具体活动,可以查看论坛。
原理
原理部分不涉及代码,涉及背景介绍,熟悉的同学可以略过。因为midjourney
官方没有提供API功能,所以有国外大神将开源了一款模拟请求工具,来请求midjourney,laf将这代码集成到内部的npm包中。如果需要github地址,欢迎留言,我私信给您。
所以laf平台,加上下面的实例代码可以很好的快速接入到系统中。
开始
要现有个laf账号,会有免费1月的试用,本次调用mj(以下代指midjourney),所以要在laf.dev
上注册使用,这是运行在新加坡环境上。
代码逻辑
我的核心思想是这样的:先要有个核心与midjourney
交互的代码,上层的我们想做的业务逻辑可以自己定义。
代码
laf 是一个云开发平台,可以将代码暴露成api形式,进行调用,一些其他鉴权等,可以在之前我写的文章中找到灵感:腾讯云开发迁移实录
要做一个云函数,处理与midjourney交互,我这里起名云函数mj-send
import cloud from '@lafjs/cloud' import { Midjourney, MidjourneyMessage } from 'midjourney' const SERVER_ID = '' // Midjourney 服务 ID const CHANNEL_ID = '' // Midjourney 频道 ID const SALAI_TOKEN = '' // Midjourney 服务 Token const Limit = 100 const MaxWait = 3 const client = new Midjourney({ ServerId: SERVER_ID, ChannelId: CHANNEL_ID, SalaiToken: SALAI_TOKEN, Debug: true, SessionId: SALAI_TOKEN, Limit: Limit, MaxWait: MaxWait }); export default async function (ctx: FunctionContext) { const { type, param } = ctx.body switch (type) { case 'RetrieveMessages': return await RetrieveMessages(param) case 'imagine': return await imagine(param) case 'upscale': return await upscale(param) case 'variation': return await variation(param) } } // 查询最近消息 async function RetrieveMessages(param) { console.log("RetrieveMessages") const client = new MidjourneyMessage({ ChannelId: CHANNEL_ID, SalaiToken: SALAI_TOKEN, }); const msg = await client.RetrieveMessages(); console.log("RetrieveMessages success ", msg) return msg } // 创建生图任务 async function imagine(param) { console.log("imagine", param) const { question, msg_Id } = param const msg = await client.Imagine( `[${msg_Id}] ${question}`, (uri: string, progress: string) => { console.log("loading", uri, "progress", progress); } ); console.log("imagine success ", msg) return true } // upscale 放大图片 async function upscale(param) { console.log("upscale", param) const { question, index, id, url } = param const hash = url.split("_").pop()?.split(".")[0] ?? "" console.log(hash) const msg = await client.Upscale( question, index, id, hash, (uri: string, progress: string) => { console.log("loading", uri, "progress", progress); } ); console.log("upscale success ", msg) return msg } // variation 变换图片 async function variation(param) { console.log("variation", param) const client = new Midjourney({ ServerId: SERVER_ID, ChannelId: CHANNEL_ID, SalaiToken: SALAI_TOKEN, Debug: true, SessionId: SALAI_TOKEN, Limit: Limit, MaxWait: 100 }); const { question, index, id, url } = param const hash = url.split("_").pop()?.split(".")[0] ?? "" const msg = await client.Variation( question, index, id, hash, (uri: string, progress: string) => { console.log("loading", uri, "progress", progress); } ); console.log("variation success ", msg) return msg }
什么?没有账号?仔细看帖,里面有获取方式
什么?已经有了midjourney付费账号,没有key?大佬我们做朋友,留言我来告诉你。
发布即可调用,怎么调用?我把curl给你,你看看结构就懂了,该替换的替换。
画图需要一些时间,这里默认使用的fast,但也是会花时间的,所以成图我们要在之后调用查询接口查看。
question
:就是prompt,这里要输入英文。 关注下参数msg_Id
,后面有用 curl --location --request POST 'https://<你的发布地址服务>' \ --header 'User-Agent: apifox/1.0.0 (https://www.apifox.cn)' \ --header 'Content-Type: application/json' \ --data-raw '{ "type": "imagine", "param": { "question": "a dog", "msg_Id": 1684585158 } }'
查询 curl --location --request POST 'https://<你的发布地址服务>' \ --header 'User-Agent: apifox/1.0.0 (https://www.apifox.cn)' \ --header 'Content-Type: application/json' \ --data-raw '{ "type":"RetrieveMessages" }'
如何获取到我刚创建的图呢?先看一下返回的结果。
[ { "id": "1109565864640008202", "type": 0, "content": "**[1684582132] a dog --seed 8925 --v 5** - <@1013684342851117146> (fast)", "channel_id": "1109368983364313204", "author": { "id": "936929561302675456", "username": "Midjourney Bot", "global_name": null, "avatar": "4a79ea7cd151474ff9f6e08339d69380", "discriminator": "9282", "public_flags": 589824, "bot": true, "avatar_decoration": null }, "attachments": [ { "id": "1109565863994077215", "filename": "johnsonmaureen_1684582132_a_dog_a062b5e2-ab39-40b0-b281-1365695529d5.png", "size": 4275948, "url": "https://cdn.discordapp.com/attachments/1109368983364313204/1109565863994077215/johnsonmaureen_1684582132_a_dog_a062b5e2-ab39-40b0-b281-1365695529d5.png", "proxy_url": "https://media.discordapp.net/attachments/1109368983364313204/1109565863994077215/johnsonmaureen_1684582132_a_dog_a062b5e2-ab39-40b0-b281-1365695529d5.png", "width": 2048, "height": 2048, "content_type": "image/png" } ] } **省略其他数据** ]
返回结果为数组,还记得上面的msg_Id
吗,在JSON结构中查看content
部分,就可以看到 "content": "**[1684582132] a dog --seed 8925 --v 5** - <@1013684342851117146> (fast)",
所以,我们可以用这个字段来进行筛选。$.attachments[0].url
就是成图了。
如果再返回的四张图有一张看得不错,怎么生成大图呢?先给你个表格,告诉你哪是1,哪是3 1 2 3 4
然后来看如何传参
curl --location --request POST 'https://<你的发布地址服务>' \ --header 'User-Agent: apifox/1.0.0 (https://www.apifox.cn)' \ --header 'Content-Type: application/json' \ --data-raw '{ "type": "upscale", "param": { "id": "1109460470152319086", "question":"a dog", "index": 3, "url":"https://cdn.discordapp.com/attachments/1109368983364313204/1109460469628022915/johnsonmaureen_1684585158_a_dog_d5b7e35c-0fce-4f7d-b440-35f5602d2f25.png" } }'
解释下参数:
id: 是查询返回结果体里的id question,是最开始输入进去的prompt
index: 你想要的第几张图 url:是查询返回结果体里的url,四张图拼一起的那个。 别问我怎么知道的,我都是翻代码看得。
重绘当看上这4张图中某一个的风格或者样式之后,可以根据这个风格重绘。
curl --location --request POST 'https://<你的发布地址服务>' \ --header 'User-Agent: apifox/1.0.0 (https://www.apifox.cn)' \ --header 'Content-Type: application/json' \ --data-raw '{ "type": "variation", "param": { "id": "1109460470152319086", "question": "a dog", "index": 3, "url": "https://cdn.discordapp.com/attachments/1109368983364313204/1109460469628022915/johnsonmaureen_1684585158_a_dog_d5b7e35c-0fce-4f7d-b440-35f5602d2f25.png" } }'
参数解释不说了,跟上面类似。
至此教程结束了
赶紧去上手做点什么吧,实践出真知~
作品展示
这次其实是laf在组织活动,想我这种平台级别思考大佬的人,不会去钻到某个应用当中,我来看看大家都画了什么图,所以我做了个简陋的页面,本人前端能力有限,代码实现全靠ChatGPT。
上链接:
laf比赛作品大赏
如果觉得不错打个赏吧,后面是答疑环节
问题
我怎么知道mj的图画完没有呢?可以根据
$.attachments[0].width
的尺寸大小来看,如果小于2048,则没有生成完,没生成完其实应该是512。 怎么让图片结果与请求msg_Id绑定?正如上文所说要自己实现一个逻辑去匹配结果,另外还有一个就是用好触发器,他会定时执行你的服务,这样你就可以将数据进行增量处理。
`
codemidjourneyurlapitokenappclipngjsondiscordcdnavatardebugbotprompt查询接口npm包chatgptgitproxychat免费使用开发平台githubgpt放大图片