首页 > 其他分享 >Midjourney模拟API生图调用

Midjourney模拟API生图调用

时间:2024-01-25 10:45:13浏览次数:32  
标签:生图 String type id API message Midjourney event

image.png
目前Midjourney没有对外开放API接口,所以通过MJ自动化生图的主要方式是,集成Discord应用机器人,通过机器人与MJ机器人进行交互,并监听频道内的生图结果,最终拿到图片地址。
简单介绍下步骤

一、购买MJ账号

命令行中输入/subscribe指令并回车
点击跳转按钮
MJ资费

二、获取账号Authorization

在网页中向Midjourney Bot发送/imagine进行生图
我们在检查元素中能够获取调用的地址和Authorization
image.png

三、模拟Http请求调用

public String generateImage(String promptText) {
    Map<String, String> headerMap = Maps.newHashMap();
    // 添加付费账号对应的 authorization
    headerMap.put("authorization", getAuthorization());
    headerMap.put("Content-Type", "application/json");
    // 构建请求(详见下方payload_json)
    InteractionsRequest req = buildInteractionsRequest(promptText);
    String reqJson = JSON.toJSONString(req);
    log.info("===reqJson is {}", reqJson);
    try {
        // POST请求需要代理
        String res = HttpUtils.httpPostProxy(MidjourneyContants.API_URL, reqJson, headerMap);
        return res;
    } catch (Exception e) {
        log.error("VolcanoTtsService generateVoice error,request={}", reqJson, e);
    }
    return StringUtils.EMPTY;
}
{
  "type": 2, // 注意:type为2不能缺少
  "application_id": "",
  "guild_id": "",
  "channel_id": "",
  "session_id": "",
  "data": {
    "version": "",
    "id": "",
    "name": "imagine",
    "type": 1,
    "options": [
      {
        "type": 3,
        "name": "prompt",
        "value": "a beautiful lady"
      }
    ],
    "application_command": {
      "id": "",
      "application_id": "",
      "version": "",
      "default_member_permissions": null,
      "type": 1,
      "nsfw": false,
      "name": "imagine",
      "description": "Create images with Midjourney",
      "dm_permission": true,
      "contexts": null,
      "options": [
        {
          "type": 3,
          "name": "prompt",
          "description": "The prompt to imagine",
          "required": true
        }
      ]
    },
    "attachments": [ ]
  },
  "nonce": ""
}

四、Discord机器人监听消息

之前写过监听消息的方法,这里就不再赘述了
Discord 机器人Java Api使用

1、生图完成结果

生图结果是四张图的拼图
image.png
我们收到的响应通过debug可以看到
image.png
需要关注:

  1. 我们的prompt在响应中是在event.message.content中可以获得,前后有**标识
private static final String PROMPT_MARKER = "**";

private String getPromptBetweenMarkers(String messageContent, String marker) {
    return str.substring(str.indexOf(marker) + marker.length(), str.lastIndexOf(marker));
}
  1. 如果我们想获取U1的单张图片,那么需要获取上图的messageIdU1对应的customId两个参数

五、调用获取单张图片

获取单图的所调用的Http地址与生图相同,不通的是Body中的payload_json。所需要的参数如下:

{
  "type": 3, // 注意:type为3不能错
  "nonce": "",
  "guild_id": "",
  "channel_id": "",
  "message_flags": 0,
  "message_id": "生图响应中的messageId",
  "application_id": "",
  "session_id": "",
  "data": {
    "component_type": 2,
    "custom_id": "生图响应中的customId"
  }
}

响应:
image.png

六、外网图片转换

获取的MJ单图图片是外网图片,转换成内网的方式有很多,比如说先下载本地File再上传到自己的图床等

七、Discord监听器完整代码

@Slf4j
@Component
public class ImageGenerateComplete implements MessageCreateListener {

    @Autowired
    private IMidjourneyService midjourneyService;

    @Override
    public void onMessageCreate(MessageCreateEvent event) {
        // 反转为Spring的Bean管理
        ImageGenerateComplete self = SpringUtil.getBean(this);
        BizExecutor.getInstance().getThreadPool().execute(() -> self.eventSolution(event));
    }

    public void eventSolution(MessageCreateEvent event) {
        try{
            MessageAuthor messageAuthor = event.getMessageAuthor();
            // 消息发送这是否为机器人
            if(messageAuthor.isBotUser()){
                // 发送人id,可用来校验是否为需要监听的应用
                long messageAuthorId = messageAuthor.getId();
                Message message = event.getMessage();
                long messageId = message.getId();
                // 生图返回的消息类型为NORMAL。点击U1生成单图的消息类型为REPLY
                if(MessageType.NORMAL.equals(message.getType())){
                    // 示例默认取U1,非空校验略
                    String customId = message.getComponents().get(0).asActionRow().orElse(null)
                        .getComponents().stream().filter(c -> c.asButton().orElse(null).getLabel().orElse("").equals("U1")).findFirst().orElse(null)
                        .asButton().orElse(null).getCustomId().orElse(null);
                    // 获取单张图片服务
                    midjourneyService.getSingleImage(messageId, customId);
                }
            }
        }catch (Exception e) {
            log.info("!==[ImageGenerateComplete#eventSolution] ex is " + e.getMessage());
            // do sth.
        }
    }
}
@Slf4j
@Component
public class SingleImageComplete implements MessageCreateListener {

    private static final String PROMPT_MARKER = "**";

    @Resource
    private IMidjourneryBiz midjourneryBiz;

    @Override
    public void onMessageCreate(MessageCreateEvent event) {
        // 反转为Spring的Bean管理
        SingleImageComplete self = SpringUtil.getBean(this);
        BizExecutor.getInstance().getThreadPool().execute(() -> self.eventSolution(event));
    }

    public void eventSolution(MessageCreateEvent event) {
        try{
            MessageAuthor messageAuthor = event.getMessageAuthor();
            if(messageAuthor.isBotUser()){
                Message message = event.getMessage();
                long messageId = message.getId();
                if(MessageType.REPLY.equals(message.getType())){
                    String messageContent = message.getContent();
                    // 获取prompt
                    String prompt = getStringBetweenMarkers(messageContent, PROMPT_MARKER);
                    // 获取图片地址
                    String discordImageUrl = event.getMessage().getAttachments().get(0).getUrl().toString();
                    // 转内网图片地址
                }
            }
        }catch (Exception e) {
            log.info("!==[SingleImageComplete#eventSolution] ex is " + e.getMessage());
        }
    }

    private String getStringBetweenMarkers(String str, String marker) {
        return str.substring(str.indexOf(marker) + marker.length(), str.lastIndexOf(marker));
    }

}

可参考我的GitHub:
all-in-one/springboot/aigc at master · Meidanlong/all-in-one

标签:生图,String,type,id,API,message,Midjourney,event
From: https://www.cnblogs.com/meidanlong/p/17986624

相关文章

  • Midjourney获取seed值
    一、请求:envelope:curl'https://discord.com/api/v9/channels/1116337317276287057/messages/1124159098066305135/reactions/%E2%9C%89%EF%B8%8F/%40me?location=Message&type=0'\-X'PUT'\-H'authority:discord.com'\-H'......
  • Midjourney人物一致性探索
    原图a25yearsoldmaleinancientChineserobewithblackbigbackhairandsmalleyesandnormalnoseandsmallmouthandasmallface垫图https://s.mj.run/gBMdKDa7UJo,a25yearsoldmaleinancientChineserobewithblackbigbackhairandsmalle......
  • 学习Java8中StreamAPI的笔记
    本次笔记记录一下我自己学习Stream流的一个情况。第一种:使用Stream流来代替增强for循环进行赋值:这是使用增强for循环的写法:publicstaticvoidmain(String[]args){ArrayList<String>strings=newArrayList<>();strings.add("张三");strings.add("李四");strings.add......
  • Apiserver -- 停掉问题排查
    1.错误133环境中apiserver总是停掉,重启kubelet会让apiserver启动,但过一段时间就会停掉kubectlgetnodes#==>错误Theconnectiontotheserver192.168.0.133:6443wasrefused-didyouspecifytherighthostorport?2.排错过程#1.查询apiserver进程ps-e......
  • Linux网络编程基础API
    目录socket地址API创建socket命名socket监听socket接收连接发起连接关闭连接数据读写带外标记地址信息函数socket选项网络信息APIsocket地址API主机字节序和网络字节序在Linux系统中,主机字节序(HostByteOrder)和网络字节序(NetworkByteOrder)是两个重要的概念。主机字节序......
  • Apipost自动化测试+Jenkins实现持续集成
    Apipost自动化测试支持「持续集成」功能,在安装了Apipost的服务器中输入命令,即可运行测试脚本。创建自动化测试脚本在创建好的测试用例中选择「持续集成」 点击新建,配置运行环境、循环次数、间隔停顿后点击保存会生成命令。 安装Apipost-clinpminstall-gapipost-cl......
  • 如何让你的.NET WebAPI程序支持HTTP3?
    下面我将总结构建Http3的经验,以TokenGateway的项目为例,请注意使用Http3之前你需要知道它的限制,WindowsWindows11版本22000或更高版本/WindowsServer2022。TLS1.3或更高版本的连接。Linux已安装libmsquic包。实现讲解首先我们需要拉取我们的代码gitcloneh......
  • FastAPI 如何处理请求和响应?
    FastAPI处理请求和响应的流程主要包括以下几个步骤:定义路由:使用FastAPI的FastAPI类创建一个应用实例,然后使用装饰器(如@app.get、@app.post等)定义路由和请求方法。pythonCopycodefromfastapiimportFastAPIapp=FastAPI()@app.get("/items/{item_id}")defread......
  • Gateway API 实践之(四)FSM Gateway 的重试功能
    网关的重试功能是一种重要的网络通信机制,旨在提高系统服务调用的可靠性和容错性。这个功能允许网关在初次请求失败时自动重新发送请求,从而减少临时性问题(如网络波动、服务瞬时过载等)对最终用户体验的影响。它的工作原理是,当网关向下游服务发送请求时,如果遇到特定类型的失败(如连接错......
  • 使用Spring Boot实现基于HTTP的API
    SpringBoot是一个用于简化Spring应用程序开发的框架,它提供了一系列的开箱即用的功能,使得快速构建RESTfulWeb服务和基于HTTP的API变得简单。以下是使用SpringBoot实现基于HTTP的API的步骤:1. 添加依赖:在Maven项目中,将SpringBootWebStarter依赖添加到pom.xml文件中。2. java复......