API 参考Seedream
Seedream v4.5 图生图
Seedream v4.5 图生图 API 文档,基于源图片和文本描述进行图像编辑和风格转换。
Seedream v4.5 图生图 API 允许您基于文本描述和参考图片对现有图像进行转换和编辑。
- 支持 1-14 张源图片作为参考
- 支持中英文 Prompt 描述
- 多种宽高比选择:1:1, 2:3, 3:2, 3:4, 4:3, 16:9, 9:16, 21:9
- 高分辨率输出:支持 2K 和 4K 分辨率
- 异步任务模式:提交请求后轮询获取结果
接口定义
POST
https://api.apipod.ai/v1/images/generations
异步任务模式
此 API 为异步操作,提交请求后会返回任务 ID,需要轮询状态接口获取结果。
步骤:1. 提交任务并附带源图片获取 task_id → 2. 轮询状态接口直到完成
# 步骤 1: 提交图像编辑任务
curl --request POST \
--url https://api.apipod.ai/v1/images/edits \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "seedream-v4.5-edit",
"prompt": "将这张肖像照转换为油画风格,保持原有构图但添加丰富的笔触和纹理",
"image_urls": [
"https://example.com/images/source.jpg"
],
"aspect_ratio": "3:4",
"quality": "2K"
}'
# 响应示例:
# {"code": 0, "message": "success", "data": {"task_id": "task_edit_abc123xyz"}}
# 步骤 2: 轮询任务状态
curl --request GET \
--url https://api.apipod.ai/v1/images/status/task_edit_abc123xyz \
--header 'Authorization: Bearer <token>'import requests
import time
API_KEY = "<token>"
BASE_URL = "https://api.apipod.ai/v1"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
# 步骤 1: 提交图像编辑任务
response = requests.post(
f"{BASE_URL}/images/edits",
headers=headers,
json={
"model": "seedream-v4.5-edit",
"prompt": "将这张肖像照转换为油画风格,保持原有构图但添加丰富的笔触",
"image_urls": [
"https://example.com/images/source.jpg"
],
"aspect_ratio": "3:4",
"quality": "2K"
}
)
task_id = response.json()["data"]["task_id"]
print(f"任务已提交: {task_id}")
# 步骤 2: 轮询任务状态
while True:
status_response = requests.get(
f"{BASE_URL}/images/status/{task_id}",
headers=headers
)
data = status_response.json()["data"]
if data["status"] == "completed":
print("图像编辑完成!")
print("图片 URL:", data["result"])
break
elif data["status"] == "failed":
print("任务失败")
break
else:
print(f"状态: {data['status']},等待中...")
time.sleep(2) # 每 2 秒轮询一次const API_KEY = "<token>";
const BASE_URL = "https://api.apipod.ai/v1";
const headers = {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json"
};
async function editImage() {
// 步骤 1: 提交图像编辑任务
const submitResponse = await fetch(`${BASE_URL}/images/edits`, {
method: "POST",
headers,
body: JSON.stringify({
model: "seedream-v4.5-edit",
prompt: "将这张肖像照转换为油画风格,保持原有构图",
image_urls: [
"https://example.com/images/source.jpg"
],
aspect_ratio: "3:4",
quality: "2K"
})
});
const { data: { task_id } } = await submitResponse.json();
console.log(`任务已提交: ${task_id}`);
// 步骤 2: 轮询任务状态
while (true) {
const statusResponse = await fetch(
`${BASE_URL}/images/status/${task_id}`,
{ headers }
);
const { data } = await statusResponse.json();
if (data.status === "completed") {
console.log("图像编辑完成!");
console.log("图片 URL:", data.result);
break;
} else if (data.status === "failed") {
console.log("任务失败");
break;
} else {
console.log(`状态: ${data.status},等待中...`);
await new Promise(resolve => setTimeout(resolve, 2000));
}
}
}
editImage();package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
)
const (
apiKey = "<token>"
baseURL = "https://api.apipod.ai/v1"
)
type SubmitResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
TaskID string `json:"task_id"`
} `json:"data"`
}
type StatusResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
TaskID string `json:"task_id"`
Status string `json:"status"`
CompletedAt int64 `json:"completed_at"`
Result []string `json:"result"`
} `json:"data"`
}
func main() {
// 步骤 1: 提交图像编辑任务
payload := map[string]interface{}{
"model": "seedream-v4.5-edit",
"prompt": "将这张肖像照转换为油画风格",
"image_urls": []string{
"https://example.com/images/source.jpg",
},
"aspect_ratio": "3:4",
"quality": "2K",
}
jsonData, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", baseURL+"/images/edits", bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
var submitResp SubmitResponse
json.Unmarshal(body, &submitResp)
taskID := submitResp.Data.TaskID
fmt.Printf("任务已提交: %s\n", taskID)
// 步骤 2: 轮询任务状态
for {
req, _ := http.NewRequest("GET", baseURL+"/images/status/"+taskID, nil)
req.Header.Set("Authorization", "Bearer "+apiKey)
resp, _ := client.Do(req)
body, _ := ioutil.ReadAll(resp.Body)
resp.Body.Close()
var statusResp StatusResponse
json.Unmarshal(body, &statusResp)
if statusResp.Data.Status == "completed" {
fmt.Println("图像编辑完成!")
fmt.Println("图片 URL:", statusResp.Data.Result)
break
} else if statusResp.Data.Status == "failed" {
fmt.Println("任务失败")
break
} else {
fmt.Printf("状态: %s,等待中...\n", statusResp.Data.Status)
time.Sleep(2 * time.Second)
}
}
}import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class SeedreamEditExample {
private static final String API_KEY = "<token>";
private static final String BASE_URL = "https://api.apipod.ai/v1";
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
// 步骤 1: 提交图像编辑任务
String payload = """
{
"model": "seedream-v4.5-edit",
"prompt": "将这张肖像照转换为油画风格",
"image_urls": ["https://example.com/images/source.jpg"],
"aspect_ratio": "3:4",
"quality": "2K"
}
""";
HttpRequest submitRequest = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/images/edits"))
.header("Authorization", "Bearer " + API_KEY)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
HttpResponse<String> submitResponse = client.send(submitRequest,
HttpResponse.BodyHandlers.ofString());
JsonObject submitJson = JsonParser.parseString(submitResponse.body()).getAsJsonObject();
String taskId = submitJson.getAsJsonObject("data").get("task_id").getAsString();
System.out.println("任务已提交: " + taskId);
// 步骤 2: 轮询任务状态
while (true) {
HttpRequest statusRequest = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/images/status/" + taskId))
.header("Authorization", "Bearer " + API_KEY)
.GET()
.build();
HttpResponse<String> statusResponse = client.send(statusRequest,
HttpResponse.BodyHandlers.ofString());
JsonObject statusJson = JsonParser.parseString(statusResponse.body()).getAsJsonObject();
String status = statusJson.getAsJsonObject("data").get("status").getAsString();
if ("completed".equals(status)) {
System.out.println("图像编辑完成!");
System.out.println("图片 URL: " + statusJson.getAsJsonObject("data").get("result"));
break;
} else if ("failed".equals(status)) {
System.out.println("任务失败");
break;
} else {
System.out.println("状态: " + status + ",等待中...");
Thread.sleep(2000);
}
}
}
}认证鉴权
所有接口调用均需在 Header 中包含 Bearer Token。
安全提示
请勿在浏览器前端代码中直接暴露您的 API Key。建议仅在服务器端使用。
Authorization: Bearer sk-xxxxxxxxxxxxxxxx请求参数
核心参数
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
model | string | 是 | seedream-v4.5-edit | 模型标识符 |
prompt | string | 是 | - | 描述如何编辑图像,最大长度 4000 字符 |
image_urls | array | 是 | - | 源图片 URL 列表(需要 1-14 张图片) |
aspect_ratio | string | - | 1:1 | 输出图像的宽高比 |
quality | string | - | 2K | 输出图像分辨率 |
源图片要求
图片要求
- 最少:需要 1 张图片
- 最多:支持最多 14 张图片
- 格式:JPEG、PNG、WebP
- 可访问性:图片必须是可公开访问的 URL
多图片使用场景:
| 图片数量 | 使用场景 |
|---|---|
| 1 张图片 | 单图风格迁移或编辑 |
| 2-3 张图片 | 多参考图的风格融合 |
| 4 张以上 | 复杂场景合成或多参考编辑 |
图像编辑 Prompt 编写技巧
描述转换方式
清晰描述您希望如何转换源图片。
将这张照片转换为水彩画风格指定风格细节
添加您想要应用的具体风格特征。
边缘柔和、粉彩色调、可见的笔触效果保留或修改元素
指定从原图中要保留什么、要改变什么。
保持原有构图但将背景更换为日落场景完整 Prompt 示例:
将这张肖像照转换为油画风格,保持原有构图和面部特征,
但添加丰富的笔触、饱满的纹理,以及温暖的金色光线,呈现文艺复兴肖像画的风格。宽高比选项
| 值 | 比例 | 适用场景 |
|---|---|---|
1:1 | 正方形 | 头像、社交媒体图片 |
2:3 | 竖版 | 人像摄影 |
3:2 | 横版 | 风景摄影 |
3:4 | 竖版 | 杂志封面、海报 |
4:3 | 横版 | 传统照片 |
16:9 | 宽屏 | 视频封面、Banner |
9:16 | 竖屏 | 手机壁纸、短视频封面 |
21:9 | 超宽屏 | 电影画幅、网站 Hero 图 |
分辨率选项
| 值 | 说明 |
|---|---|
2K | 标准分辨率,生成速度较快 |
4K | 高分辨率,适合印刷和大尺寸展示 |
响应结构
任务提交响应
提交图像编辑请求后,API 会返回任务 ID:
| 字段 | 类型 | 说明 |
|---|---|---|
code | integer | 响应状态码,0 表示成功 |
message | string | 响应消息 |
data.task_id | string | 编辑任务的唯一标识 |
{
"code": 0,
"message": "success",
"data": {
"task_id": "task_edit_abc123xyz"
}
}状态查询接口
GET
https://api.apipod.ai/v1/images/status/{task_id}
| 路径参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_id | string | 是 | 图像编辑任务 ID |
状态响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
code | integer | 响应状态码,0 表示成功 |
message | string | 响应消息 |
data.task_id | string | 任务 ID |
data.error_message | string | 错误消息 |
data.status | string | 任务状态:pending / processing / completed / failed |
data.completed_at | integer | 完成时间戳(Unix timestamp) |
data.result | array | 编辑后的图片 URL 列表 |
任务状态说明
| 状态 | 说明 | 建议操作 |
|---|---|---|
pending | 任务已提交,等待处理 | 继续轮询,建议间隔 2 秒 |
processing | 任务正在处理中 | 继续轮询,建议间隔 2 秒 |
completed | 任务完成,图像已编辑 | 获取 result 中的图片 URL |
failed | 任务失败 | 检查错误信息,重新提交任务 |
轮询建议
建议每 2-3 秒轮询一次任务状态,图像编辑通常需要 15-45 秒,具体取决于源图片数量。请勿过于频繁轮询,以免触发速率限制。
错误处理
| 状态码 | 说明 |
|---|---|
400 | 请求参数错误(如 image_urls 无效、图片数量超限等) |
401 | 认证失败,API Key 无效或缺失 |
403 | 余额不足或权限不足 |
404 | 任务不存在(查询状态时) |
429 | 请求过于频繁,触发速率限制 |
500 | 服务器内部错误 |
{
"error": {
"message": "image_urls 必须包含 1 到 14 张图片",
"type": "invalid_request_error",
"code": "invalid_parameter"
}
}最佳实践
确保图片可访问
确保所有源图片 URL 可公开访问并返回有效的图片内容。
优化源图片质量
使用高质量的源图片以获得更好的效果。建议最低分辨率为 512x512。
合理设置轮询间隔
建议每 2-3 秒轮询一次,设置最大轮询次数(如 90 次),避免无限等待。
缓存编辑后的图片
图片 URL 有效期有限,建议下载并存储到自己的服务器或 CDN。