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

Midjourney模拟API生图调用

时间:2023-12-20 09:34:58浏览次数:40  
标签:生图 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/17915443.html

相关文章

  • 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......
  • API 接口设计最佳实践
    前言 最近团队内部在做故障复盘的时候发现有很多故障都是因为接口设计不当导致的,这里我就整理归纳一下在接口设计层面需要注意的地方。API接口设计Token设计 Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此To......
  • 支持可视化提取变量,Apipost配置变量不要太简单
    在调试接口时我们需要将响应结果中的某个字段配置为环境变量在其他接口中引用,之前在Apipost中需要配置脚本而在最近Apipost后执行操作中可以进行可视化的断言和变量提取,无需配置繁琐脚本。这里我们在登录接口下配置一条Token环境变量,在后执行脚本-添加操作项-选择提取变量 输......
  • 拼多多ID取商品详情API:电商行业的核心价值与实时数据获取策略
    一、引言在当今的电商行业中,数据是驱动业务决策和优化用户体验的关键因素。拼多多作为中国电商市场的主要参与者,其根据ID取商品详情原数据的API在电商行业中具有显著的重要性。本文将深入探讨这个话题,并介绍如何实现实时数据获取。二、拼多多根据ID取商品详情原数据API的重要性1.提......
  • 高德地图api报错 Get geolocation timeout.Get ipLocation failed.
    使用了https报错Getgeolocationtimeout.GetipLocationfailed. 报错是定位超时,由于JSAPI使用的是浏览器提供的定位服务,所以定位的准确度和成功率都会对浏览器有很大的依赖。由于Chrome在国内没有提供服务,因此使用Chrome定位服务的浏览器,比如:Chrome、火狐、安卓原生WebVie......
  • 腾讯云api-python调用
    https://cloud.tencent.com/document/product/1278/46716#-*-coding:utf-8-*-importhashlib,hmac,json,os,sys,timefromdatetimeimportdatetime#密钥参数#需要设置环境变量TENCENTCLOUD_SECRET_ID,值为示例的AKIDz8krbsJ5yK**********mLPx3EXAMPLEsecret_......
  • P4630 [APIO2018] 铁人两项 题解
    今天学习了圆方树,并且做了一道和这道题很像的题,于是就又来做了一下这道题。题意给定一张不保证连通的无向图。求有多少个点对\((a,b,c)\)满足\(a\)到\(c\)的简单路径上经过了点\(b\)。思路显然圆方树。点双缩点过后构造一颗圆方树,然后考虑如何计算答案。圆方树有一个实......
  • WebAPI局域网访问出错(经验总结)
    WebAPI局域网访问出错(经验总结)经验一:未设置入站规则方法:控制面板->系统和安全->WindowsDefender防火墙->高级设置->入站规则->新建规则->端口->,如图:下一页特定本地端口为WebAPI在IIS中设置的端口号。选择允许连接,最后起个名称完成即可。即可通过此设备......
  • 如何通过ETLCloud的API对接功能实现各种SaaS平台数据对接
    前言当前使用SaaS系统的企业越来越多,当我们需要对SaaS系统中产生的数据进行分析和对接时就需要与SaaS系统提供的API进行对接,因为SaaS一般是不会提供数据库表给企业,这时就应该使用ETL(Extract, Transform, Load)的API对接功能。虽然SaaS平台也提供了部分集成其他数据库或系统的能......