不用魔法,快速、手摸手上线Midjourney!【附源码】【示例】

news2024/11/23 17:25:47

首先来一波感谢:
感谢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
12
34

然后来看如何传参

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绑定?
    正如上文所说要自己实现一个逻辑去匹配结果,另外还有一个就是用好触发器,他会定时执行你的服务,这样你就可以将数据进行增量处理。

`

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/549929.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Freertos的ESP-IDF开发——7.WS2812B彩色灯循环

基于Freertos的ESP-IDF开发——7.WS2812B彩色灯循环 0. 前言1. WS2812B简介2. 完整代码3. 演示效果4. 其他FreeRtos文章 0. 前言 本节使用WS2812B实现彩灯循环 开发环境&#xff1a;ESP-IDF 4.3 操作系统&#xff1a;Windows10 专业版 开发板&#xff1a;自制的ESP32-WROOM-3…

【软考中级】软件设计师选择题题集(一)

海明校验码是在n个数据位之外增设k个校验位,从而形成一个k+n位的新的码字, 使新的码字的码距比较均匀地拉大。n与k的关系是(1)。 (1)A.2k - 1≥n + k  B.2n - 1≤ n + k   C.n = k  D.n-1≤k 【答案】A 【解析】 【答案】B A 【解析】 在采用结构化方法进行系统分析时,…

MySQL高级篇——索引失效的11种情况

导航&#xff1a; 【黑马Java笔记踩坑汇总】Java基础进阶JavaWebSSMSpringBoot瑞吉外卖SpringCloud黑马旅游谷粒商城学成在线设计模式牛客面试题 目录 1. 索引优化思路 2. 索引失效的11种情况 2.0. 数据准备 2.1 要尽量满足全值匹配 2.2 要满足最佳左前缀法则 2.3 主键插…

详解Jetpack Compose中的Modifier修饰符

前言 本文将会介绍Jetpack Compose中的Modifier。在谷歌官方文档中它的描述是这么一句话&#xff1a;Modifier元素是一个有序、不可变的集合&#xff0c;它可以往Jetpack Compose UI元素中添加修饰或者各种行为。例如&#xff0c;背景、填充和单击事件监听器装饰或添加行为到文…

依次对数组中的元素进行逻辑非和异或判断numpy.logical_not()numpy.logical_xor()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 依次对数组中的元素进行逻辑非和异或判断 numpy.logical_not() numpy.logical_xor() [太阳]选择题 下列代码中np.logical_xor(A, B)输出的结果是&#xff1f; import numpy as np A [True, …

苹果新增了28个以AI为重点的职位,希望利用这种AI技术改变iPhone和iPad

&#x1f680; 苹果新增了28个以AI为重点的职位&#xff0c;希望利用这种AI技术改变iPhone和iPad 苹果公司限制了使用ChatGPT等外部AI工具&#xff0c;正在开发自主的生成式AI技术。 苹果此前新增了28个以AI为重点的职位&#xff0c;希望利用这种AI技术改变iPhone和iPad。 此…

IntelliJ 导出和导入配置文件

导出&#xff1a; File->Manage IDE Setting->Export Settings…->选择导出目录&#xff0c;可以得到一个 settings.zip 的文件 导入方法&#xff1a; File->Manage IDE Setting->Import Settings…->选择需要导入的文件即可&#xff0c;导入之后重启IDE。

13-2-CSS3-渐变色、2D转换、3D转换

一、渐变色 CSS渐变色&#xff08;Gradient&#xff09;是指在元素背景中使用两种或多种不同的颜色进行过渡&#xff0c;超过两个颜色可以形成更为细腻的渐变效果。常见的CSS渐变色有线性渐变和径向渐变。 1. 线性渐变&#xff1a;Linear Gradients 向下/向上/向左/向右/对角…

CyberLink的屏幕录制软件Screen Recorder Deluxe 4.3版本在win10系统的下载与安装配置教程

目录 前言一、Screen Recorder Deluxe安装二、使用配置总结 前言 Screen Recorder Deluxe是由CyberLink公司开发的一款高效的屏幕录制工具&#xff0c;该软件提供了全面而易于使用的功能&#xff0c;可以满足广泛的屏幕录制需求。 Screen Recorder Deluxe的一些主要特点&…

代码随想录算法训练营 Day 46 | 139.单词拆分,关于多重背包,你该了解这些!,背包问题总结篇!

139.单词拆分 讲解链接&#xff1a;代码随想录-139.单词拆分 确定 dp 数组以及下标的含义&#xff1a;dp[i] : 字符串长度为 i 的话&#xff0c;dp[i]为 true&#xff0c;表示可以拆分为一个或多个在字典中出现的单词。 确定递推公式&#xff1a;如果确定 dp[j] 是 true&…

PyTorch-Dataset

Dataset类&#xff1a; 如何获取数据及标签。 Dataloader类&#xff1a;为之后的网络提供不同的数据形式。 1. 数据文件夹表示&#xff1a; from torch.utils.data import Dataset from PIL import Image import osclass MyData(Dataset):def __init__(self, root_dir, label_d…

三十七、雪崩问题、Sentinel、簇点链路、流控模式

1、初识Sentinel 1.1雪崩问题 微服务调用链路中的某个服务故障&#xff0c;引起整个链路中的所有微服务都不可用&#xff0c;这就是雪崩。 解决雪崩问题的常见方式有四种&#xff1a; 超时处理&#xff1a;设定超时时间&#xff0c;请求超过一定时间没有响应就返回错误信息&am…

Rust每日一练(Leetday0006) 三数之和、字母组合、四数之和

目录 16. 最接近的三数之和 3Sum Closest &#x1f31f;&#x1f31f; 17. 电话号码的字母组合 Letter-combinations-of-a-phone-number &#x1f31f;&#x1f31f; 18. 四数之和 4Sum &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Rust…

肝一肝设计模式【九】-- 享元模式

系列文章目录 肝一肝设计模式【一】-- 单例模式 传送门 肝一肝设计模式【二】-- 工厂模式 传送门 肝一肝设计模式【三】-- 原型模式 传送门 肝一肝设计模式【四】-- 建造者模式 传送门 肝一肝设计模式【五】-- 适配器模式 传送门 肝一肝设计模式【六】-- 装饰器模式 传送门 肝…

java枚举类解读

目录 为什么需要枚举类 枚举类的使用 枚举类的实现 枚举类的属性 自定义枚举类 使用enum定义枚举类 常见enum的使用场景 switch 向枚举中添加新方法 覆盖枚举的方法 Enum类的主要方法 实现接口的枚举类 为什么需要枚举类 类的对象只有有限个&#xff0c;确定的。…

如何将map与对象进行转换

Spring Boot内置了一个强大的JSON转换器Jackson&#xff0c;可以实现将JSON字符串或Map类型的数据转换成Java对象。以下是将Map类型的数据转换成Java对象的示例代码&#xff1a; import com.fasterxml.jackson.databind.ObjectMapper;//定义Java对象 public class User {priva…

oracle客户端的安装教程

文章目录 一、安装前的准备工作 1.1、百度网盘安装包的连接 1.2、百度网盘oracle11g软件包 二、oracle数据库客户端的安装与数据的准备 安装步骤 前言 本文主要讲解oracle客户端的安装与简单使用过程 一、安装前的准备工作 1.1、百度网盘安装包的连接 客户端的软件包 …

STM32 FMC篇-SDRAM(IS42S16400J)

IS42S16400J 这个东西太常见啦&#xff0c;长方形的。不会过多解释&#xff0c;详细请阅读它的数据手册。 IS42S16400J是一种高速同步动态随机存储器(SDRAM)&#xff0c;64Mb的存储容量&#xff0c;采用4个bank&#xff0c;每个bank大小为16Mb&#xff0c;总线宽度为16位&…

【CW32开发】00 开发环境搭建和示例代码运行

1.下载MDK 2.下载芯片相关的固件库 我用的是芯片是CW32F030系列&#xff0c;所以下载相应的固件库 下载地址&#xff1a;https://www.whxy.com/support/filelist/13 3.安装固件库 解压下载的文件&#xff0c;并在cw32f030-stdperiph-lib\IdeSupport\MDK路径下安装固件库 …

064:cesium设置点划线材质(material-8)

第064个 点击查看专栏目录 本示例的目的是介绍如何在vue+cesium中设置点划线材质,请参考源代码,了解PolylineDashMaterialProperty的应用。 直接复制下面的 vue+cesium源代码,操作2分钟即可运行实现效果. 文章目录 示例效果配置方式示例源代码(共89行)相关API参考:专栏…