26j文档
试一试 →

Grok Imagine 2.0 Ext 图层与选区编辑

使用 segment 获取对象图层和精确遮罩,并通过 region_edit 按多边形、矩形或对象索引编辑指定区域。

segment 和 region_edit 均使用现有异步图片入口。创建任务后保存 task_id,再轮询 获取任务状态;不要等待创建请求直接返回图层或图片。

不要把 API Key 写入浏览器包、LocalStorage、URL 或前端日志。浏览器应调用业务 BFF,由服务端持有 Key 并转发请求。

请求示例
curl --request POST \
  --url https://26j.cn/v1/images/generations \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header 'Idempotency-Key: 6baf0940-25d6-4ec2-9131-925250840fa7' \
  --data '{
    "model": "grok-imagine-2.0-ext",
    "operation": "segment",
    "image_urls": ["https://26j.cn/f/image/..."],
    "cache_only": true,
    "include_mask_rle": false
  }'
const response = await fetch("https://26j.cn/v1/images/generations", {
  method: "POST",
  headers: {
    Authorization: "Bearer <token>",
    "Content-Type": "application/json",
    Accept: "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    model: "grok-imagine-2.0-ext",
    operation: "region_edit",
    image_id: "<SOURCE_IMAGE_ID>",
    prompt: "把选中的跑车改成亮红色,保持其他画面不变",
    selection_regions: [
      {
        outer: {
          points: [0.12, 0.2, 0.48, 0.2, 0.48, 0.61, 0.12, 0.61],
        },
      },
    ],
  }),
});

console.log(response.status, await response.json());
响应示例
{
  "code": 200,
  "data": [
    {
      "status": "submitted",
      "task_id": "task_..."
    }
  ]
}
{
  "error": {
    "message": "Invalid selection regions",
    "type": "invalid_selection_regions",
    "param": "selection_regions",
    "code": "invalid_selection_regions"
  }
}

操作概览

操作 用途 关键输入 完成结果 计费
segment 识别对象并获取图层、边界框和精确遮罩 source_task_id,或包含一张已上传图片的 image_urls image_id、image_url、objects 免费
region_edit 修改多边形、矩形或对象所在区域 segment 返回的 image_id、编辑提示词和选区 新图片 URL 和新 image_id 按完成任务结算

完整链路:

已完成的 Grok 单图任务 task_id ─┐
                               ├→ segment
上传图片返回的公网图片 URL ──────┘
  → image_id + objects[].mask_rle
  → 前端把 mask 转为 selection_regions
  → region_edit(image_id, prompt, selection_regions)
  → 新图片 URL + 新 image_id

segment 必须且只能选择一种来源:source_task_id 或 image_urls。source_task_id、image_urls 和 image_id 不可互换;region_edit 仍使用 segment 返回的图片资产 ID。编辑后重新获取图层时,将本次 region_edit 的 task_id 作为新的 source_task_id。

请求头

Authorizationstring必填

使用 Bearer Token:Bearer <APIMART_API_KEY>。

Content-Typestring必填

固定为 application/json。

Idempotency-Keystring

可选。付费的 region_edit 强烈建议使用。支持 1–191 个可见 ASCII 字符,推荐 UUID。

每次新的逻辑操作使用一个新 Key。网络失败重试同一次请求时,必须复用原 Key 和完全相同的请求体。

同一个 Key 的任务仍在处理时,接口可能返回 409 idempotency_in_progress。如果返回 idempotency_result_indeterminate,停止自动重提并保留原 Key;尤其不要为结果不确定的付费 region_edit 生成新 Key。

异步任务流程

创建任务成功返回 HTTP 200,任务 ID 位于 data[0].task_id。随后查询:

GET https://26j.cn/v1/tasks/{task_id}?language=zh
Authorization: Bearer <APIMART_API_KEY>
Accept: application/json

状态可能为 pending、processing、completed 或 failed。建议从 2 秒间隔开始轮询,逐步退避到最多 5 秒,并设置 10 分钟总超时。切换源图或离开页面时,使用 AbortController 终止旧轮询。

任务查询即使返回 HTTP 200,data.status 仍可能是 failed。必须根据 data.status 判断任务成败,并展示 data.error。

获取图层:segment

请求参数

modelstring必填默认 grok-imagine-2.0-ext

固定为 grok-imagine-2.0-ext。

operationstring必填默认 segment

获取图层时固定为 segment。

nsfw_checkboolean默认 false

是否在提交图层解析任务前执行内容审核。

  • true:使用 omni-moderation-latest 审核来源图片
  • false 或不传:不发起审核请求,不增加审核成本与延迟(默认)
source_task_idstring

当前用户已完成的 Grok 单图任务 ID。来源任务必须成功、属于图片任务,且最终结果仅包含一张图片。

与 image_urls 二选一。不要同时发送 image_id 或 image_index;服务端会从来源任务解析对应资产。

image_urlsstring[]

上传图片来源。数组中必须且只能包含一个公网可访问的绝对 http:// 或 https:// URL。

与 source_task_id 二选一。本地图片请先调用 上传图片,再把返回的 url 放入数组。使用此来源时必须设置 cache_only=true,且不要发送 cached_only 或 refresh。

include_mask_rleboolean默认 true

是否返回 COCO compressed RLE。设为 false 时仍会返回 image_id、对象索引和边界框,但不返回 RLE 遮罩;需要精确描边、画笔或多边形编辑时应显式设为 true。

cache_onlyboolean默认 false

仅查询分段缓存,未命中时不回源。使用 image_urls 时固定为 true;使用 source_task_id 时不能与 refresh=true 同时使用。

cached_onlyboolean默认 false

传递给上游的缓存提示,不代表本地一定命中缓存。仅适用于 source_task_id 来源。

refreshboolean默认 false

强制跳过缓存重新获取。仅适用于 source_task_id 来源;不要用于普通编辑器流程,也不能与 cache_only=true 同时使用。

segment 不需要 prompt,也不要发送 billing_model_name、n、size 或 response_format。source_task_id 与 image_urls 必须二选一,不能同时发送或同时省略。

请求示例

使用任务 ID
{
  "model": "grok-imagine-2.0-ext",
  "operation": "segment",
  "source_task_id": "<COMPLETED_SINGLE_IMAGE_TASK_ID>",
  "include_mask_rle": true,
  "cached_only": false
}
使用上传图片
{
  "model": "grok-imagine-2.0-ext",
  "operation": "segment",
  "image_urls": ["https://26j.cn/f/image/..."],
  "cache_only": true,
  "include_mask_rle": false
}
任务缓存探测
{
  "model": "grok-imagine-2.0-ext",
  "operation": "segment",
  "source_task_id": "<COMPLETED_SINGLE_IMAGE_TASK_ID>",
  "include_mask_rle": true,
  "cache_only": true
}

使用 cache_only=true 时,缓存未命中仍是成功任务。根据 cache_status 判断:hit 可直接显示图层,miss 表示尚无缓存。不要用 cached 字段判断是否命中。

从本地上传图片

先通过上传接口把本地文件换成公网 URL:

curl --request POST \
  --url https://26j.cn/v1/uploads/images \
  --header 'Authorization: Bearer <token>' \
  --form 'file=@/path/to/source.png'

上传成功后读取响应中的 url,将其作为唯一的 image_urls 元素提交给 segment。后续异步轮询、完成响应以及 region_edit 的调用方式都与 source_task_id 来源一致:从完成结果中读取 result.image_id 和 objects,再提交选区编辑。上传 URL 为临时地址,默认保留 72 小时。

image_urls 仅接受一张公网可访问的绝对 HTTP(S) URL。图片来源模式只支持 cache_only=true;不要同时发送 source_task_id、cached_only 或 refresh。

完成响应

segment 的 data.result 直接是分段结果,不包在 images 中:

{
  "code": 200,
  "data": {
    "id": "task_...",
    "status": "completed",
    "progress": 100,
    "cost": 0,
    "credits_cost": 0,
    "result": {
      "created": 1786784507,
      "source_task_id": "task_...",
      "image_id": "6b78a7c3-5f9e-4a3d-a928-9e9b42113a3f",
      "image_url": "https://.../source.jpg",
      "cached": false,
      "from_cache": true,
      "cache_status": "hit",
      "objects": [
        {
          "index": 0,
          "name": "red sports car",
          "box_xyxy": [38.1, 689.8, 945.8, 1065.4],
          "score": 0.9765625,
          "mask_size": [1792, 1008],
          "mask_url": "",
          "mask_rle": {
            "size": [1792, 1008],
            "counts": "..."
          }
        }
      ]
    }
  }
}
字段 说明
result.image_id 来源图片的资产 ID,后续 region_edit 使用此值
result.image_url 与 image_id 对齐的公网 HTTP(S) 图片 URL
objects[].index 服务端原始对象索引;使用 object_indices 时必须原样保留
objects[].box_xyxy mask 像素坐标 [x1,y1,x2,y2]
objects[].score 识别置信度,可能为 null
objects[].mask_size [height,width],不可写死图片尺寸
objects[].mask_rle COCO compressed RLE,精确描边的首选数据
objects[].mask_url 可选的遮罩图片 URL,可能为空

没有有效 mask_rle 或 mask_url 的对象只能用于矩形近似编辑,不能标记为精确图层。

解码 mask_rle

mask_rle.counts 是 COCO 压缩计数字符串,不是 Base64,也不是 zlib。数据按列优先顺序展开;第一个 run 表示背景像素数,此后在背景和前景之间交替。

以下 TypeScript 将结果转换为浏览器常用的行优先二值数组:

export interface CocoRLE {
  size: [height: number, width: number];
  counts: string;
}

export interface BinaryMask {
  width: number;
  height: number;
  data: Uint8Array; // data[y * width + x]
}

function decodeCompressedCounts(counts: string): number[] {
  const runs: number[] = [];
  let cursor = 0;

  while (cursor < counts.length) {
    let value = 0;
    let shift = 0;
    let more = true;

    while (more) {
      if (cursor >= counts.length) throw new Error("截断的 COCO RLE counts");
      const current = counts.charCodeAt(cursor++) - 48;
      value |= (current & 0x1f) << shift;
      more = (current & 0x20) !== 0;
      shift += 5;
      if (!more && (current & 0x10) !== 0) value |= -1 << shift;
    }

    if (runs.length > 2) value += runs[runs.length - 2] ?? 0;
    if (value < 0) throw new Error(`非法 COCO RLE run: ${value}`);
    runs.push(value);
  }

  return runs;
}

export function decodeCocoRLE(rle: CocoRLE): BinaryMask {
  const [height, width] = rle.size;
  if (!Number.isInteger(height) || !Number.isInteger(width) || height <= 0 || width <= 0) {
    throw new Error(`非法 mask size: ${JSON.stringify(rle.size)}`);
  }

  const pixelCount = width * height;
  if (!Number.isSafeInteger(pixelCount) || pixelCount > 32_000_000) {
    throw new Error(`mask 像素数超出前端安全上限: ${pixelCount}`);
  }
  if (typeof rle.counts !== "string" || rle.counts.length === 0) {
    throw new Error("缺少 COCO RLE counts");
  }

  const data = new Uint8Array(pixelCount);
  const runs = decodeCompressedCounts(rle.counts);
  let position = 0;
  let foreground = false;

  for (const run of runs) {
    if (position + run > data.length) throw new Error("COCO RLE 超出 mask_size");
    if (foreground) {
      for (let offset = 0; offset < run; offset++) {
        const columnMajorIndex = position + offset;
        const y = columnMajorIndex % height;
        const x = (columnMajorIndex - y) / height;
        data[y * width + x] = 1;
      }
    }
    position += run;
    foreground = !foreground;
  }

  if (position !== data.length) {
    throw new Error(`COCO RLE 只覆盖 ${position}/${data.length} 个像素`);
  }

  return { width, height, data };
}

大尺寸遮罩建议在 Web Worker 中解码,避免阻塞主线程。不要把完整 mask_rle.counts 写入日志、埋点、URL 或错误上报。

转换为精确选区

region_edit 使用归一化多边形:

export interface SelectionBoundary {
  points: number[]; // [x0,y0,x1,y1,...],坐标范围 0~1
}

export interface SelectionRegion {
  outer: SelectionBoundary;
  holes?: SelectionBoundary[];
}

将二值 mask 转为多边形时,建议提取连通区域和孔洞,再用 Douglas–Peucker 简化。每个 ring 至少 3 个不同点,不能自交或面积为 0;每个图层最多保留面积最大的 16 个 region,每个 ring 最多保留 400 个点。

mask_size 的顺序是 [height,width],坐标基于原始 mask,不是 CSS 显示尺寸。使用 object-fit: contain 时,需要先扣除留白偏移并按实际绘制区域换算,最后将坐标限制在 0~1。

如果前端需要读取源图或 mask_url 的像素,图片服务器必须允许当前站点跨域访问,并且要在设置 src 前指定 image.crossOrigin = "anonymous",或通过 fetch 获取 Blob。否则图片绘制到 Canvas 后会污染画布,无法再读取像素。图层轮廓优先直接解码 mask_rle,不依赖跨域读取源图。

编辑选区:region_edit

请求参数

modelstring必填默认 grok-imagine-2.0-ext

固定为 grok-imagine-2.0-ext。

operationstring必填默认 region_edit

编辑选区时固定为 region_edit。

nsfw_checkboolean默认 false

是否在提交选区编辑任务前执行内容审核。

  • true:使用 omni-moderation-latest 审核编辑提示词和输入图片
  • false 或不传:不发起审核请求,不增加审核成本与延迟(默认)
image_idstring必填

当前源图的资产 ID。首次编辑使用 segment 响应中的 result.image_id;连续编辑使用上次编辑返回的新 image_id。

promptstring必填

描述如何修改选区,去除首尾空格后不能为空。

selection_regionsarray

精确多边形选区,推荐用于正式图层和画笔编辑。坐标归一化到 0~1,支持 outer 和可选 holes。

boxesnumber[][]

矩形选区,每项为 [x1,y1,x2,y2]。可使用归一化坐标;使用像素坐标时必须同时传 mask_size。

object_indicesinteger[]

segment 返回的原始 objects[].index。上游按对象边界框编辑,因此只适合快速联调或矩形近似模式。

mask_sizeinteger[]

像素 boxes 使用的 [height,width]。两个值都必须为正整数。

selection_regions、boxes、object_indices 至少有一个非空。接口允许组合,但建议一次只使用一种,避免重叠选区和语义不清。

不要发送 billing_model_name、size、aspect_ratio、source_aspect_ratio、source_size 或 image_urls。n 只能省略或设为 1;claim_asset 只能省略或设为 false;response_format 只能省略或设为 url;不支持 Base64 输出和 stream=true。

三种选区方式

精确多边形(推荐)
{
  "model": "grok-imagine-2.0-ext",
  "operation": "region_edit",
  "image_id": "<SOURCE_IMAGE_ID>",
  "prompt": "把选中的跑车改成亮红色,保持其他画面不变",
  "selection_regions": [
    {
      "outer": {
        "points": [0.12, 0.20, 0.48, 0.20, 0.48, 0.61, 0.12, 0.61]
      },
      "holes": [
        {
          "points": [0.30, 0.35, 0.38, 0.35, 0.38, 0.45, 0.30, 0.45]
        }
      ]
    }
  ]
}
`points` 可使用扁平数组,也兼容 `[[x0,y0],[x1,y1],...]`。每项必须是 `0~1` 的有限数字,每个 ring 至少包含 3 对坐标。
归一化矩形
{
  "model": "grok-imagine-2.0-ext",
  "operation": "region_edit",
  "image_id": "<SOURCE_IMAGE_ID>",
  "prompt": "把框内车辆改成亮红色",
  "boxes": [[0.04, 0.385, 0.938, 0.594]]
}
像素矩形
{
  "model": "grok-imagine-2.0-ext",
  "operation": "region_edit",
  "image_id": "<SOURCE_IMAGE_ID>",
  "prompt": "把框内车辆改成亮红色",
  "boxes": [[40, 689.6, 945.9, 1064.4]],
  "mask_size": [1792, 1008]
}
每个 box 必须恰好包含 4 个非负有限数字,并满足 `x2>x1`、`y2>y1`。
对象索引
{
  "model": "grok-imagine-2.0-ext",
  "operation": "region_edit",
  "image_id": "<SOURCE_IMAGE_ID>",
  "prompt": "把选中的跑车改成亮红色,保持其他画面不变",
  "object_indices": [0]
}
索引必须来自同一 `image_id` 的 segment 响应。不要使用前端过滤、排序或分组后重新生成的数组下标。

完成响应

{
  "code": 200,
  "data": {
    "id": "task_...",
    "status": "completed",
    "progress": 100,
    "cost": 0.016,
    "credits_cost": 0.16,
    "result": {
      "images": [
        {
          "url": ["https://.../result.jpg"],
          "image_ids": ["<NEW_IMAGE_ID>"],
          "items": [
            {
              "url": "https://.../result.jpg",
              "image_id": "<NEW_IMAGE_ID>",
              "source_image_id": "<SOURCE_IMAGE_ID>",
              "role": "region_edit",
              "prompt": "把选中的跑车改成亮红色,保持其他画面不变"
            }
          ],
          "expires_at": 1787040000
        }
      ]
    }
  }
}

优先读取 result.images[0].items[0]。兼容旧响应时,可读取同一下标的 url[0] 和 image_ids[0],但必须同时拿到可展示的 HTTP(S) URL 和新的 image_id。

interface RegionEditResult {
  images?: Array<{
    url?: string[];
    image_ids?: string[];
    items?: Array<{
      url?: string;
      image_id?: string;
    }>;
  }>;
}

function readRegionEditOutput(result: RegionEditResult): {
  url: string;
  imageId: string;
} {
  const group = result.images?.[0];
  const item = group?.items?.[0];

  if (item?.url && item.image_id && /^https?:\/\//i.test(item.url)) {
    return { url: item.url, imageId: item.image_id };
  }

  if (
    group?.url?.length &&
    group.image_ids?.length === group.url.length &&
    /^https?:\/\//i.test(group.url[0]) &&
    group.image_ids[0]
  ) {
    return { url: group.url[0], imageId: group.image_ids[0] };
  }

  throw new Error("选区编辑完成,但结果缺少对齐的 HTTP(S) URL 或 image_id");
}

结果 URL 的有效期以 expires_at 为准,不要在前端硬编码固定小时数。需要长期展示时应及时下载或转存。

连续编辑

一次编辑完成后,应同时更新三个值并清除旧图层缓存:

const output = readRegionEditOutput(task.data.result);

editor.sourceTaskId = task.data.id;   // 下一次 segment 使用
editor.sourceImageId = output.imageId; // 下一次 region_edit 使用
editor.sourceUrl = output.url;         // 编辑器展示
editor.layers = [];
  • 再次获取图层:source_task_id = 本次 region_edit 的 task_id
  • 再次编辑:image_id = 本次 region_edit 返回的新 image_id
  • 不要把 image_id 传给 segment,也不要继续使用上一张图片的旧 image_id

错误处理

HTTP / 状态 错误码 常见原因 建议处理
400 invalid_operation operation 缺失或不受支持 只使用 segment 或 region_edit
400 invalid_source source_task_id 与 image_urls 同时发送或同时省略 两种 segment 来源严格二选一
400 invalid_image_urls URL 不是公网 HTTP(S) 地址,或数组不是恰好一项 先上传图片,并只发送返回的一个 url
400 invalid_source_task segment 来源任务不可用,或传入 image_id / image_index 使用当前用户已完成的 Grok 单图任务 ID
400 invalid_request 图片来源未设 cache_only=true,或发送了 cached_only / refresh 图片来源只保留 cache_only=true
400 conflicting_cache_flags 同时使用 cache_only 和 refresh 二选一
400 missing_image_id region edit 缺少资产 ID 使用 segment 返回的 result.image_id
400 empty_prompt 编辑提示词为空 阻止提交并提示用户输入修改描述
400 invalid_selection_regions 无选区、坐标、点数或 box 非法 在前端校验并标记问题选区
400 invalid_object_index 对象索引非法 保留同一图片 segment 返回的原始索引
400 invalid_claim_asset claim_asset=true 省略或设为 false
400 invalid_n n 不是 1 省略或设为 1
400 invalid_response_format 请求 Base64 等不支持格式 省略或使用 url
400 invalid_stream 请求流式响应 移除 stream
401 / 403 鉴权或权限错误 Key 无效或模型未开通 检查服务端 Key 和账户权限
402 余额不足 付费编辑无法创建 提示充值后重试
409 幂等冲突 同一 Key 正在处理、请求体变化或结果不确定 遵循响应码,不要换 Key 自动重提
429 请求过多 触发限流 按 Retry-After 退避
failed task_failed 异步任务执行失败 停止轮询并展示 data.error.message

部分越界的正整数 object_indices 可能在创建后异步失败,因此创建请求成功不代表编辑一定成功。

计费说明

  • segment 免费,完成任务的 cost 和 credits_cost 均为 0,但仍需正常鉴权并满足来源输入条件。
  • region_edit 为付费操作。以任务完成响应中的 cost 和 credits_cost 为准,不要在前端硬编码价格。
  • 不要发送内部计费字段 billing_model_name。

前端接入检查

  • API Key 只保存在后端或 BFF。
  • segment 仅发送一种来源:已有任务使用 source_task_id,上传图片使用只含一个公网 URL 的 image_urls;不要发送 image_id 或 image_index。
  • 使用 image_urls 时设置 cache_only=true,且不发送 cached_only 或 refresh。
  • region_edit 使用 segment 返回的 image_id,并至少提供一种选区。
  • 正式图层编辑使用 selection_regions;object_indices 仅为矩形近似。
  • mask_size 始终按 [height,width] 解析,并正确处理图片显示区域的缩放和留白。
  • 同一次网络重试复用原 Idempotency-Key,收费请求结果不确定时不自动换 Key 重提。
  • 任务完成后同时校验 URL 和新 image_id,连续编辑时清理旧图层和旧轮询。

This documentation is built and hosted on Mintlify, a developer documentation platform.

© 2026 26j.cn · AI 模型中转站