1
创建访问令牌
登录 MindSee 控制台,打开左下角的用户菜单,进入「令牌」,新建一个令牌。
令牌明文只在创建时显示一次,请立即复制并妥善保存,不要提交到代码仓库或暴露在前端代码里。
2
发起请求
把令牌放进环境变量,然后调用生图接口:接口是同步的,生成过程中连接会保持打开,通常需要几十秒。
export MINDSEE_API_KEY="你的访问令牌"
curl https://openapi.mindsee.app/v1/images/generations \
--max-time 330 \
-H "Authorization: Bearer $MINDSEE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "一只橘猫坐在窗台上看雨,水彩风格",
"resolution": "1K",
"ratio": "3:4"
}' \
-o response.json
3
保存图片
响应里的
data[0].b64_json 是图片的 base64,解码后即可保存:jq -r '.data[0].b64_json' response.json | base64 --decode > cat.png
代码示例
import base64
import os
import requests
resp = requests.post(
"https://openapi.mindsee.app/v1/images/generations",
headers={"Authorization": f"Bearer {os.environ['MINDSEE_API_KEY']}"},
json={
"model": "gpt-image-2",
"prompt": "一只橘猫坐在窗台上看雨,水彩风格",
"resolution": "1K",
"ratio": "3:4",
},
timeout=330,
)
resp.raise_for_status()
with open("cat.png", "wb") as f:
f.write(base64.b64decode(resp.json()["data"][0]["b64_json"]))
import { writeFile } from 'node:fs/promises'
const resp = await fetch('https://openapi.mindsee.app/v1/images/generations', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.MINDSEE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'gpt-image-2',
prompt: '一只橘猫坐在窗台上看雨,水彩风格',
resolution: '1K',
ratio: '3:4',
}),
signal: AbortSignal.timeout(330_000),
})
if (!resp.ok) {
throw new Error((await resp.json()).message)
}
const { data } = await resp.json()
await writeFile('cat.png', Buffer.from(data[0].b64_json, 'base64'))
package main
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
"os"
"time"
)
func main() {
body, _ := json.Marshal(map[string]any{
"model": "gpt-image-2",
"prompt": "一只橘猫坐在窗台上看雨,水彩风格",
"resolution": "1K",
"ratio": "3:4",
})
req, _ := http.NewRequest(
http.MethodPost,
"https://openapi.mindsee.app/v1/images/generations",
bytes.NewReader(body),
)
req.Header.Set("Authorization", "Bearer "+os.Getenv("MINDSEE_API_KEY"))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 330 * time.Second}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result struct {
Message string `json:"message"`
Data []struct {
B64JSON string `json:"b64_json"`
} `json:"data"`
}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
panic(err)
}
if resp.StatusCode != http.StatusOK {
panic(fmt.Sprintf("%d: %s", resp.StatusCode, result.Message))
}
image, err := base64.StdEncoding.DecodeString(result.Data[0].B64JSON)
if err != nil {
panic(err)
}
if err := os.WriteFile("cat.png", image, 0o644); err != nil {
panic(err)
}
}
// 依赖:com.fasterxml.jackson.core:jackson-databind
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.Base64;
import java.util.Map;
public class GenerateImage {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
String body = mapper.writeValueAsString(Map.of(
"model", "gpt-image-2",
"prompt", "一只橘猫坐在窗台上看雨,水彩风格",
"resolution", "1K",
"ratio", "3:4"
));
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://openapi.mindsee.app/v1/images/generations"))
.timeout(Duration.ofSeconds(330))
.header("Authorization", "Bearer " + System.getenv("MINDSEE_API_KEY"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = mapper.readTree(response.body());
if (response.statusCode() != 200) {
throw new RuntimeException(response.statusCode() + ": " + result.path("message").asText());
}
String b64 = result.path("data").get(0).path("b64_json").asText();
Files.write(Path.of("cat.png"), Base64.getDecoder().decode(b64));
}
}
// 依赖:com.squareup.okhttp3:okhttp、org.json:json
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
import java.io.File
import java.util.Base64
import java.util.concurrent.TimeUnit
fun main() {
val body = JSONObject()
.put("model", "gpt-image-2")
.put("prompt", "一只橘猫坐在窗台上看雨,水彩风格")
.put("resolution", "1K")
.put("ratio", "3:4")
.toString()
.toRequestBody("application/json".toMediaType())
val request = Request.Builder()
.url("https://openapi.mindsee.app/v1/images/generations")
.header("Authorization", "Bearer ${System.getenv("MINDSEE_API_KEY")}")
.post(body)
.build()
val client = OkHttpClient.Builder()
.callTimeout(330, TimeUnit.SECONDS)
.readTimeout(330, TimeUnit.SECONDS)
.build()
client.newCall(request).execute().use { response ->
val result = JSONObject(response.body!!.string())
if (!response.isSuccessful) {
error("${response.code}: ${result.optString("message")}")
}
val b64 = result.getJSONArray("data").getJSONObject(0).getString("b64_json")
File("cat.png").writeBytes(Base64.getDecoder().decode(b64))
}
}
// 依赖:http
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
Future<void> generateImage(String apiKey, String savePath) async {
final response = await http
.post(
Uri.parse('https://openapi.mindsee.app/v1/images/generations'),
headers: {
'Authorization': 'Bearer $apiKey',
'Content-Type': 'application/json',
},
body: jsonEncode({
'model': 'gpt-image-2',
'prompt': '一只橘猫坐在窗台上看雨,水彩风格',
'resolution': '1K',
'ratio': '3:4',
}),
)
.timeout(const Duration(seconds: 330));
final result = jsonDecode(utf8.decode(response.bodyBytes)) as Map<String, dynamic>;
if (response.statusCode != 200) {
throw HttpException('${response.statusCode}: ${result['message']}');
}
final b64 = (result['data'] as List).first['b64_json'] as String;
await File(savePath).writeAsBytes(base64Decode(b64));
}
import Foundation
struct ImageGenerationResponse: Decodable {
struct Item: Decodable {
let b64_json: String
}
let data: [Item]
}
struct ErrorResponse: Decodable {
let message: String
}
func generateImage(apiKey: String, saveTo fileURL: URL) async throws {
var request = URLRequest(url: URL(string: "https://openapi.mindsee.app/v1/images/generations")!)
request.httpMethod = "POST"
request.timeoutInterval = 330
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try JSONSerialization.data(withJSONObject: [
"model": "gpt-image-2",
"prompt": "一只橘猫坐在窗台上看雨,水彩风格",
"resolution": "1K",
"ratio": "3:4",
])
let (data, response) = try await URLSession.shared.data(for: request)
let statusCode = (response as! HTTPURLResponse).statusCode
if statusCode != 200 {
let error = try JSONDecoder().decode(ErrorResponse.self, from: data)
throw NSError(
domain: "MindSee",
code: statusCode,
userInfo: [NSLocalizedDescriptionKey: error.message]
)
}
let result = try JSONDecoder().decode(ImageGenerationResponse.self, from: data)
try Data(base64Encoded: result.data[0].b64_json)!.write(to: fileURL)
}
编辑图片
在image 里传入待编辑图片的 base64(最多 8 张,必须带 data URL 前缀,如 data:image/png;base64,),接口会按提示词编辑图片:
jq -n --rawfile image <(base64 < input.png | tr -d '\n') '{
"model": "gpt-image-2",
"prompt": "把背景换成海边日落",
"image": ["data:image/png;base64," + $image],
"resolution": "auto",
"ratio": "auto"
}' | curl https://openapi.mindsee.app/v1/images/generations \
--max-time 330 \
-H "Authorization: Bearer $MINDSEE_API_KEY" \
-H "Content-Type: application/json" \
-d @- \
-o response.json
各模型可用的分辨率、比例和质量取值不同,参见左侧「模型」分组下的各模型页面。
