SpringBoot对接Midjourney Api

news2024/12/24 0:19:15

提示:SpringBoot对接Midjourney Api

文章目录

目录

文章目录

后端代码

导包

controller层

工具类层

前端代码

申请API

测试结果



后端代码

导包

        <!--添加hutool的依赖-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.16</version>
        </dependency>

        <!-- OkHttp -->
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.9.3</version>
        </dependency>

        <!-- Gson -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.9</version>
        </dependency>

controller层

    @PostMapping("/createimage")
    public Response createimage(String prompt){
        System.out.println(prompt);
        return new Response("0","success",ApiTestUtil.createImage(prompt));
    }

    @PostMapping("/fetch")
    public Response fetch(String jobId){
        String result = ApiTestUtil.fetch(jobId);
        return new Response("0","success",result);
    }

工具类层

    public static String createImage(String prompt) {
        Map<String, Object> map = new HashMap<>();
        map.put("prompt", prompt);
        map.put("mode", "fast");
        map.put("hookUrl", "");
        String result = HttpRequest.post("https://api.ttapi.io/midjourney/v1/imagine")
                .body(JSONUtil.toJsonStr(map))
                .header("TT-API-KEY", "请替换你自己的key")
                .execute().body();
        System.out.println("绘图请求响应:" + result);
        return result;
    }

    public static String fetch(String jobId){
        String result = HttpRequest.get("https://api.ttapi.io/midjourney/v1/fetch?jobId=" + jobId)
                .header("TT-API-KEY", "请替换你自己的key")
                .execute().body();
        System.out.println("绘图结果:" + result);
        return result;
    }

前端代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>AI Chat Interface</title>
  <!-- 引入 Vue 3 的 CDN -->
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <!-- 引入 Font Awesome for avatars -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
  <style>
    /* 样式 */
    body {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      background-color: #f4f4f9;
      margin: 0;
      padding: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
    }

    .chat-container {
      display: flex;
      flex-direction: column;
      height: 80vh;
      width: 80vw;
      max-width: 600px;
      border: 1px solid #ccc;
      border-radius: 10px;
      overflow: hidden;
      background-color: #fff;
    }

    .chat-window {
      flex: 1;
      padding: 10px;
      overflow-y: auto;
      background-color: #f4f4f9;
      position: relative;
    }

    .chat-message {
      display: flex;
      margin-bottom: 10px;
      align-items: flex-start;
    }

    .message-left {
      flex-direction: row;
    }

    .message-right {
      flex-direction: row-reverse;
    }

    .avatar {
      width: 40px;
      height: 40px;
      border-radius: 50%;
      background-color: #007bff;
      display: flex;
      justify-content: center;
      align-items: center;
      color: white;
      font-weight: bold;
      margin: 0 10px;
      font-size: 20px;
    }

    .message-bubble {
      max-width: 70%;
      padding: 10px;
      border-radius: 20px;
      background-color: #007bff;
      color: white;
      word-wrap: break-word;
    }

    .message-left .message-bubble {
      background-color: #e4e6eb;
      color: black;
    }

    .chat-input {
      display: flex;
      padding: 10px;
      border-top: 1px solid #ccc;
      background-color: #fff;
    }

    .chat-input input {
      flex: 1;
      padding: 10px;
      border: 1px solid #ccc;
      border-radius: 20px;
      outline: none;
    }

    .chat-input button {
      margin-left: 10px;
      padding: 10px 20px;
      border: none;
      background-color: #007bff;
      color: white;
      border-radius: 20px;
      cursor: pointer;
      outline: none;
    }

    .chat-input button:hover {
      background-color: #0056b3;
    }

    .loading {
      position: relative;
      bottom: -20px;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    /* Loader animation styles */
    .loader {
      position: relative;
      width: 2.5em;
      height: 2.5em;
      transform: rotate(165deg);
    }

    .loader:before, .loader:after {
      content: "";
      position: absolute;
      top: 50%;
      left: 50%;
      display: block;
      width: 0.5em;
      height: 0.5em;
      border-radius: 0.25em;
      transform: translate(-50%, -50%);
    }

    .loader:before {
      animation: before8 2s infinite;
    }

    .loader:after {
      animation: after6 2s infinite;
    }

    @keyframes before8 {
      0% {
        width: 0.5em;
        box-shadow: 1em -0.5em rgba(225, 20, 98, 0.75), -1em 0.5em rgba(111, 202, 220, 0.75);
      }

      35% {
        width: 2.5em;
        box-shadow: 0 -0.5em rgba(225, 20, 98, 0.75), 0 0.5em rgba(111, 202, 220, 0.75);
      }

      70% {
        width: 0.5em;
        box-shadow: -1em -0.5em rgba(225, 20, 98, 0.75), 1em 0.5em rgba(111, 202, 220, 0.75);
      }

      100% {
        box-shadow: 1em -0.5em rgba(225, 20, 98, 0.75), -1em 0.5em rgba(111, 202, 220, 0.75);
      }
    }

    @keyframes after6 {
      0% {
        height: 0.5em;
        box-shadow: 0.5em 1em rgba(61, 184, 143, 0.75), -0.5em -1em rgba(233, 169, 32, 0.75);
      }

      35% {
        height: 2.5em;
        box-shadow: 0.5em 0 rgba(61, 184, 143, 0.75), -0.5em 0 rgba(233, 169, 32, 0.75);
      }

      70% {
        height: 0.5em;
        box-shadow: 0.5em -1em rgba(61, 184, 143, 0.75), -0.5em 1em rgba(233, 169, 32, 0.75);
      }

      100% {
        box-shadow: 0.5em 1em rgba(61, 184, 143, 0.75), -0.5em -1em rgba(233, 169, 32, 0.75);
      }
    }
  </style>
</head>
<body>
  <div id="app">
    <div class="chat-container">
      <div class="chat-window">
        <div v-for="(message, index) in messages" :key="index" class="chat-message" :class="{'message-left': message.isUser, 'message-right': !message.isUser}">
          <div class="avatar">
            <i :class="message.isUser ? 'fas fa-user' : 'fas fa-robot'"></i>
          </div>
          <div class="message-bubble">
            <img :src="imageUrl" alt="" style="width: 400px;height: 400px;">
          </div>
        </div>
        <div class="loading" v-if="loading">
          <div style="display: flex; align-items: center; justify-content: center;">
            <div class="loader"></div>
            <div style="margin-left: 10px; font-weight: bold; color: #e64c87;">加载中</div>
          </div>
        </div>
      </div>
      <div class="chat-input">
        <input v-model="userInput" @keydown.enter="sendMessage" placeholder="Type your question..." />
        <button @click="sendMessage">Send</button>
      </div>
    </div>
  </div>
  
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script>
    const { createApp } = Vue;

    createApp({
      data() {
        return {
          userInput: '我需要你给我画一只猫',
          messages: [
          ],
          loading: false,
          jobId:"",
          imageUrl:""
        };
      },
      methods: {
        sendMessage() {
          if (this.userInput.trim()) {
            // 添加用户的消息
            this.messages.push({ text: this.userInput, isUser: true });

            // 模拟AI回复
            this.simulateAIResponse(this.userInput);

            // 清空输入框
            this.userInput = '';
          }
        },
        
        async simulateAIResponse(userText) {
          this.loading = true;
          try {
            const res = await axios.post("http://localhost:8888/createimage", {
              "prompt": this.userInput
            }, { headers: { "Content-Type": "multipart/form-data" } });
            if(res.data.code == 0){
                this.jobId = JSON.parse(res.data.data).data.jobId;
                const result = await axios.post("http://localhost:8888/fetch",{
                    "jobId": this.jobId
            }, { headers: { "Content-Type": "multipart/form-data" } 
                });
                if(result.data.code == 0){
                   this.imageUrl = JSON.parse(result.data.data).data.discordImage
                   this.loading = false;
                }
            }
          } catch (error) {
            console.error("Error fetching AI response:", error);
          }
        },
      },
    }).mount('#app');
  </script>
</body>
</html>

申请API

https://ttapi.io/recharge

测试结果

这个主要对接了前一篇AI对话的博客,有需要自行去查找

参考博客地址:https://zhuanlan.zhihu.com/p/689296056

今日时间2024年8月29日,希望你天天开心,如有不会,请留言

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

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

相关文章

IoT客户端+联邦学习微调大模型

大型模型的训练涉及到微调&#xff0c;微调则面临着高质量数据的稀缺性。与基于集中式数据中心的解决方案相比&#xff0c;物联网-IoT中大型模型的更新面临着分布式客户端私有且异构数据的协调挑战。为了解决这一挑战&#xff0c;作者提出了KOALA来推动物联网中大模型的训练。由…

单线程Redis:Redis为什么这么快

1 Redis是不是单线程 Redis 使用后台线程执行耗时的 I/O 操作&#xff0c;以免阻塞主线程 bio_close_file&#xff1a;后台 I/O 线程之一&#xff0c;异步关闭文件 bio_aof_fsync&#xff1a;后台 I/O 线程之一&#xff0c;异步地将 AOF&#xff08;Append Only File&#xff…

C++系列-STL容器之vector

STL概念 vector基本概念vector与数组的区别vector容器的特点动态大小连续存储自动扩容尾部操作高效 vector动态扩展的含义vector常用的接口示意 vector的构造函数vector赋值操作重载赋值assign赋值 vector的容量和大小vector的插入和删除vector数据存取vector互换容器vector互换…

音视频入门基础:WAV专题(7)——FFmpeg源码中计算WAV音频文件每个packet的size值的实现

一、引言 从文章《音视频入门基础&#xff1a;WAV专题&#xff08;6&#xff09;——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道&#xff0c;通过FFprobe命令可以显示WAV音频文件每个packet&#xff08;也称为数据包或多媒体包&#xff09;的信息&#xff0…

VMware16安装包+详细安装教程

VMware Workstation Pro16.0安装 安装包下载&#xff1a; 通过百度网盘分享的文件&#xff1a;VMware16.0.rar 链接&#xff1a;https://pan.baidu.com/s/1ZSWns5kJYUmhpZFjuKXqrQ?pwdv7s2 提取码&#xff1a;v7s2右键解压之后的安装包【VMware-workstation-full-16.0.0-16…

FrameNet介绍——从同义词语义知识库到框架语义知识库

FrameNet 是一个为期三年的项目&#xff0c;获得了 NSF&#xff08;美国国家科学基金会&#xff09;的支持&#xff0c;专注于基于语料库的计算词典编纂。 项目特点 FrameNet承诺使用语料库证据&#xff08;corpus evidence&#xff09;来进行语义和句法的概括&#xff1b; 并…

网络基础-实现在Windows系统下的socket环境地址通信

实现客户端和服务端的数据交互 1.写所要实现功能的声明&#xff08;封装在tcpsocket.h文件&#xff09; #ifndef TCPSOCKET_H #define TCPSOCKET_H//在Windows下进行网络编程&#xff0c;需要引入Windows的socket库 #include <winsock2.h> //做一些预编译工作&#xff…

MyBatis结果集复杂映射超详细版(一对多关系映射)

目录 1.一对多关系映射 1.1创建两个表&#xff1a;goods表与goods_class表 1.2xml文件中两部分&#xff1a;与(存放SQL语句)1.3数据库中&#xff1a;测试SQL语句&#xff0c;涉及到的知识点&#xff1a;左连接 1.一对多关系映射 1.1创建两个表&#xff1a;goods表与goods_c…

C++对C的扩充(8.28)

1.使用C手动封装一个顺序表&#xff0c;包括成员数组1个&#xff0c;成员变量n个 代码&#xff1a; #include <iostream>using namespace std;//类型重命名 using datatype int; #define MAX 30struct seqList { private: //私有权限datatype *data; //相当于 …

【项目源码】终于有人将打字游戏和编程英语结合起来啦!编程初学者的福音

Hello&#xff01;各位彦祖&#xff0c;亦菲们&#xff01;又是美好的一天&#xff01;今天给大家分享一个Java项目源码&#xff1a;Java打字游戏项目源码&#xff01; 看到这里&#xff0c;你可能会说&#xff01; 一个破打字游戏有什么可神气的&#xff01;&#xff01;&…

【自由能系列(中级)】状态与动作的协同机制解析 ——从马尔可夫毯到大脑功能的全方位剖析

状态与动作的协同机制解析 ——从马尔可夫毯到大脑功能的全方位剖析 Synergistic Mechanism of States and Actions —— A Comprehensive Analysis from Markov Blanket to Brain Function 核心结论&#xff1a; 中文总结&#xff1a; 系统将状态划分为内部状态和隐藏或外…

Flutter中的Key

在Flutter 中&#xff0c;Key 是 几乎所有 widget 都具有的属性。为什么 widget 具有 Key 呢&#xff1f;Key的作用是什么&#xff1f; 什么是 Key Key是Widget、Element 和 SemanticNodes 的标识符。 Key 是Widget、Element 和 SemanticNodes的唯一标识。例如对于 Widget 在 …

MyBatis的学习————下篇

目录 一、动态SQL 简介 1、if标签 2、where标签 3、trim标签 4、choose、when、otherwise 5、foreach 5.1、批量删除 5.2、批量添加 6、sql标签 二、MyBatis的缓存 1、一级缓存 2、二级缓存 3、二级缓存的相关配置 4、MyBatis缓存查询的顺序 5、 第三方缓存EHCac…

如何在Windows 11上关闭无响应的应用程序?这里有详细步骤

序言 无响应的应用程序令人沮丧,但更糟糕的是这些应用程序拒绝关闭。如果你发现自己处于这种情况,我们有几种方法可以帮助你强制关闭Windows 11 PC上的这些应用程序。让我们找出可用的解决方案。 使用键盘快捷键结束程序 关闭无响应应用程序的最简单方法是使用Windows键盘…

DataWhale AI夏令营 2024大运河杯-数据开发应用创新赛-task2

DataWhale AI夏令营 2024大运河杯-数据开发应用创新赛 YOLO(You Only Look Once)上分心得分享 YOLO(You Only Look Once) YOLO算的上是近几年最火的目标检测模型了&#xff0c;被广泛的应用在工业、学术等领域。 YOLOv1&#xff08;You Only Look Once 第一版&#xff09;于 2…

基于麒麟信安操作系统的光伏发电功率预测系统完成大规模部署建设

麒麟信安操作系统&#xff0c;作为行业数智化建设的安全根基&#xff0c;为电力业务系统提供了稳定可靠的底层平台&#xff0c;在全球能源结构转型大潮中扮演着至关重要的角色。某光伏电站项目中&#xff0c;基于麒麟信安操作系统的光伏发电功率预测系统完成大规模部署建设&…

c#如何加密exe程序防止反编译附软件

1. 先说软件&#xff0c;使用的软件是Dotfuscator&#xff0c;下载地址如下&#xff1a; 链接&#xff1a;https://pan.quark.cn/s/6f2e785c003f2. 软件使用方法&#xff0c;打开软件&#xff0c;选择Create New Project 3. 找到input&#xff0c;把你需要加密的文件导入 4.…

k8s项目的发布

目录 三种发布方式 1.蓝绿发布 2.金丝雀发布&#xff08;灰度发布&#xff09; 实验&#xff1a;k8s实现金丝雀发布 3.滚动发布&#xff08;默认形式&#xff09; 因为应用升级以及新旧业务切换&#xff0c;所以在这个过程当中如何保证对外的服务正常是一个非常重要的问题…

手把手教你如何使用Python连接MySQL数据

数据库编程是在应用程序中与数据库交互和管理数据的关键部分。MySQL是一种流行的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;在Python中进行MySQL数据库编程相对容易。 本文介绍如何使用Python进行MySQL数据库编程&#xff0c;包括连接数据库、执行SQL查询…

高频面试题:SpringMVC的执行流程

SpringMVC一直以来都是面试中的重点&#xff0c;尽管随着近年来springboot和微服务的广泛流行&#xff0c;关于对springMVC的考察比重略有下降&#xff0c;但依然是面试中的重点&#xff0c;也需要我们对其有一个比较清楚和全面的认识。 如果将java的发展史中重要的组件进行排…