Перейти к основному содержанию

GPT Image 2.6 markup: редактирование по разметке и проверка слоя

Markup в GPT Image 2.6 — прозрачный PNG размером с фото: он показывает, где править, prompt — что. 200 в ответе не значит, что маршрут прочитал слой.

LaoZhang AI TeamОпубликовано10 мин чтения
Содержание
Фото кухни с четырьмя стульями, отдельный прозрачный слой с красным кругом и prompt для запроса к /v1/images/edits в GPT Image 2.6

Параметр markup в GPT Image 2.6 — это отдельный прозрачный PNG того же размера, что и фото, на котором вы обводите или зарисовываете место правки. Слой разметки отвечает на вопрос «где», а что именно поменять, вы по-прежнему пишете в prompt. Отправляется он в POST /v1/images/edits с моделью gpt-image-2.6-flare или gpt-image-2.6-sunburst: в multipart-запросе — файлом в поле markup, в JSON — объектом "markup": {"image_url": ...} или {"file_id": ...} рядом с массивом images. Это не маска: вместе с mask и prompt_rewriter слой передавать нельзя, и действует он только на первое входное изображение. OpenAI добавила разметку в API вместе с Images 2.6 4 ноября 2026 года, отдельной платы за неё нет.

Перед платным вызовом проверьте слой локально: после учёта EXIF-ориентации у него должны быть те же ширина и высота, что у фото, в нём должны быть настоящие прозрачные пиксели, не больше 16 777 216 пикселей и не больше 50 МБ. Скрипт на Python ниже собирает такой слой по координатам и проверяет все четыре правила. После ответа сравните с оригиналом всё, что лежит за пределами круга, иначе вы не узнаете, перерисовала ли модель заодно остальную картинку.

Главное условие — маршрут, через который идёт запрос. Ответ 200 не означает, что разметку прочитали: 5 ноября 2026 года поштучные маршруты LaoZhang API gpt-image-2.6-web и gpt-image-2.6-sunburst-vip приняли слой без ошибки, но обведённый стул ни разу не перекрасили, и с разметкой результат был таким же, как без неё. Поэтому markup отправляйте напрямую в OpenAI или через маршрут, который передаёт тело запроса OpenAI без изменений.

Примечание: laozhang.ai — наш собственный сервис; его цены — наши тарифы, а не независимое сравнение.

Слой разметки, маска или только текст: что выбрать для точечной правки

Слой разметки нужен, когда цель трудно назвать словами: в кадре несколько одинаковых предметов, и фраза «второй стул слева» уже не раз приводила к правке не того объекта. Если объект в кадре один и легко называется, хватит текста. Маска (mask) — другой параметр со своими правилами, и в Responses API для правки отдельной области руководство OpenAI предлагает именно её, потому что markup есть только в Image API.

Что сравниваемСлой разметки (markup)Маска (mask)Только текст
Как задаётся местоКруги, наброски и другие пометки на прозрачном PNGPNG с альфа-каналом, отмечающим область правкиОписание объекта в prompt
Где работаетТолько Image API, /v1/images/editsImage API и Responses APIВезде
Насколько точно соблюдается областьМодель видит, куда указали, но перерисовывает картинку целиком; в примере OpenAI за кругом изменилось 4,3–8,4 %По руководству OpenAI, маска — ориентир для модели, и её форма может соблюдаться неточноМодель угадывает цель; 5 ноября 2026 года без пометки жёлтым стал не тот из четырёх стульев
ОграниченияНельзя вместе с mask и prompt_rewriter; действует на первое изображениеТот же формат и размер, что у фото, меньше 50 МБ; действует на первое изображениеНет
Когда братьНесколько похожих объектов, нужно указать одинПравка через Responses API или область уже есть в виде маскиОбъект уникален в кадре

Если вы правите картинку не через API, а в приложении ChatGPT, там есть собственная кнопка разметки, и она перерисовывает изображение заново — об этом в статье Редактор фото ChatGPT: каждая кнопка заново рисует картинку.

Требования к слою markup: размер после EXIF, прозрачность, 16 777 216 пикселей

Требования к слою разметки по руководству OpenAI по генерации изображений, раздел Guide an edit with markup, по состоянию на 5 ноября 2026 года: отдельный прозрачный PNG с той же шириной и высотой, что у первого входного изображения после учёта ориентации, с прозрачными пикселями и не наложенный на оригинал. Первое изображение и слой могут содержать не больше 16 777 216 пикселей каждый (например, 4096×4096), файл слоя — не больше 50 МБ. Чаще всего ломаются первые два правила, и оба легко поймать до отправки.

ПравилоТипичная причина нарушенияКак проверяет скрипт ниже
Ширина и высота как у первого изображения после учёта ориентацииФото с телефона хранится повёрнутым и поворачивается по EXIF, а слой нарисован по другому виду; слой экспортирован в другом масштабеПоворачивает фото по EXIF и сравнивает размеры
Есть прозрачные пиксели, слой не сведён с фотоЭкспорт с «объединить слои», сохранение в JPEG, отправка фото с уже нарисованным кругомТребует RGBA и хотя бы один пиксель с альфой меньше 255
Лимит пикселей для фото и для слояСнимок с камеры на 24 МпПеремножает ширину и высоту
Лимит размера файла слояНесжатый PNG очень большого разрешенияСмотрит размер файла
Слой относится к первому изображению; остальные — референсыИсходное фото стоит в images не первымНе проверяет: это порядок в запросе
Без mask и prompt_rewriterПараметры остались от старой функции правкиНе проверяет: это поля запроса

В JSON-запросе есть ещё одно ограничение. По справочнику OpenAI по методу images.edit строка image_url не длиннее 20 971 520 символов, а base64 раздувает файл на треть, поэтому в data URL помещается примерно 15 МБ PNG (20 971 520 × 3/4 = 15 728 640 байт). Слой больше этого отправляйте через multipart или по file_id.

Четыре правила для слоя markup, результат проверки скриптом на фото 1200×900 и поля, которых не должно быть в запросе

Как собрать слой разметки и проверить его до платного вызова

Слой проще нарисовать кодом, чем в редакторе: так он гарантированно совпадёт с фото по размеру и останется прозрачным. Скрипт ниже (Python, Pillow) поворачивает фото по EXIF, рисует красный эллипс на полностью прозрачном холсте того же размера и проверяет четыре правила из предыдущего раздела. Координаты x0 y0 x1 y1 — прямоугольник, в который вписан эллипс, в пикселях фото в том виде, в каком оно отображается после поворота.

python
"""Собирает и проверяет слой разметки для правок GPT Image 2.6 / 2.5.
Рисует красный эллипс на полностью прозрачном холсте размером с фото (после учёта EXIF-ориентации)
и проверяет правила OpenAI: та же ширина и высота, что у первого входного изображения, есть прозрачные
пиксели, не больше 16 777 216 пикселей, файл не больше 50 МБ.
Запуск: python3 make_markup_overlay.py photo.jpg x0 y0 x1 y1 [out.png]"""
import os, sys
from PIL import Image, ImageDraw, ImageOps

MAX_PIXELS = 16_777_216
MAX_BYTES = 50 * 1024 * 1024


def build(photo, box, out):
    img = ImageOps.exif_transpose(Image.open(photo))  # API сравнивает размеры после учёта ориентации
    overlay = Image.new("RGBA", img.size, (0, 0, 0, 0))
    ImageDraw.Draw(overlay).ellipse(box, outline=(230, 20, 20, 255), width=max(4, img.width // 150))
    overlay.save(out)
    return img.size


def check(photo, out):
    img = ImageOps.exif_transpose(Image.open(photo))
    ov = Image.open(out)
    problems = []
    if ov.size != img.size:
        problems.append(f"size {ov.size} != photo {img.size}")
    if ov.mode != "RGBA" or ov.getchannel("A").getextrema()[0] == 255:
        problems.append("no transparent pixels (flattened overlay)")
    if ov.width * ov.height > MAX_PIXELS:
        problems.append("overlay over 16,777,216 pixels")
    if os.path.getsize(out) > MAX_BYTES:
        problems.append("overlay over 50 MB")
    return problems


if __name__ == "__main__":
    photo, *nums = sys.argv[1:6]
    out = sys.argv[6] if len(sys.argv) > 6 else "markup.png"
    size = build(photo, [int(n) for n in nums], out)
    issues = check(photo, out)
    print(f"photo {size[0]}x{size[1]} -> {out} ({os.path.getsize(out)} bytes)")
    print("OK" if not issues else "FAIL: " + "; ".join(issues))

5 ноября 2026 года скрипт прогнали на кухонном фото 1200×900 из примера OpenAI, обведя передний левый стул: команда python3 make_markup_overlay.py kitchen.png 235 610 465 785 markup.png вывела photo 1200x900 -> markup.png (5645 bytes) и OK. Готовый слой из другого источника проверяется той же функцией: python3 -c "from make_markup_overlay import check; print(check('kitchen.png', 'overlay.png'))". Слой 1000×750 к тому же фото она отклонила с сообщением size (1000, 750) != photo (1200, 900), слой, сведённый на белый фон, — с no transparent pixels (flattened overlay), а слой из примера OpenAI прошёл с пустым списком замечаний. Скрипт строгий: палитровый PNG с прозрачностью он тоже отклонит, так что сохраняйте слой в RGBA.

Проверка повторяет правила из документации OpenAI, а не ответ сервера. Она нужна потому, что некоторые маршруты не возвращают ошибку на неверный слой, и без локальной проверки вы заплатите за правку, в которой разметка ничего не значила.

Как отправить markup в /v1/images/edits: multipart и JSON

Запрос с разметкой — это обычная правка, в которую добавлено одно поле. Порядок такой:

  1. Поставьте исходное фото первым: в multipart это поле image, в JSON — первый элемент массива images. Дополнительные изображения после него модель использует как референсы, разметка к ним не относится.
  2. Передайте слой в поле markup: в multipart — файлом, в JSON — объектом ровно с одним из ключей image_url (HTTPS-адрес или base64 data URL) или file_id.
  3. В prompt назовите объект через пометку («the chair inside the red circle»), опишите изменение, перечислите, что сохранить, и попросите убрать красный круг из готового фото — так сделано в примере OpenAI. Как формулировать такие правки по схеме «измени только X, сохрани Y», разобрано в руководстве по промптам GPT Image 2.6.
  4. Задайте size явно (размеры кратны 16, соотношение сторон от 1:3 до 3:1, для фото 4:3 подходит 1536x1152) или auto. Для точечной правки OpenAI советует начинать с complexity: "low", а quality выбирать по задаче.
  5. Не передавайте mask, prompt_rewriter и input_fidelity: первые два несовместимы с разметкой, третий OpenAI просит не указывать при правках.
  6. Сохраните результат из data[0].b64_json и сравните его с оригиналом (процедура в разделе о проверке ниже).

Multipart через официальный Python SDK повторяет пример из руководства OpenAI:

python
import base64
from pathlib import Path
from openai import OpenAI

PROMPT = ("Recolor the chair inside the red circle to bright mustard-yellow leather. Keep its shape. "
          "Keep the other chairs white and keep the rest of the kitchen unchanged. "
          "Remove the red circle from the finished photo.")

client = OpenAI()  # ключ из OPENAI_API_KEY
with open("kitchen.png", "rb") as image, open("markup.png", "rb") as markup:
    result = client.images.edit(
        model="gpt-image-2.6-sunburst",
        image=("kitchen.png", image, "image/png"),
        markup=("markup.png", markup, "image/png"),
        prompt=PROMPT,
        quality="medium",
        size="1536x1152",
    )
Path("edited.png").write_bytes(base64.b64decode(result.data[0].b64_json))

В JSON входные изображения передаются массивом images, а слой — объектом. Если версия SDK у вас старая и не знает поля markup, этот вариант через requests от неё не зависит:

python
import base64, os
from pathlib import Path
import requests

def data_url(path):
    return "data:image/png;base64," + base64.b64encode(Path(path).read_bytes()).decode()

body = {
    "model": "gpt-image-2.6-sunburst",
    "images": [{"image_url": data_url("kitchen.png")}],  # первое изображение — то, которое правим
    "markup": {"image_url": data_url("markup.png")},     # ровно один ключ: image_url или file_id
    "prompt": PROMPT,                                     # тот же текст, что в примере выше
    "quality": "medium",
    "complexity": "low",
    "size": "1536x1152",
}
r = requests.post(
    "https://api.openai.com/v1/images/edits",
    headers={"Authorization": f"Bearer {os.environ['OPENAI_API_KEY']}"},
    json=body,
    timeout=300,
)
r.raise_for_status()
Path("edited.png").write_bytes(base64.b64decode(r.json()["data"][0]["b64_json"]))

Где markup действительно читается: тест маршрутов 5 ноября 2026 года

Напрямую в OpenAI разметка работает по документации и по опубликованному примеру. На поштучных маршрутах LaoZhang API gpt-image-2.6-web и gpt-image-2.6-sunburst-vip 5 ноября 2026 года она видимой разницы не дала. Тест был устроен так, чтобы текст сам по себе не подсказывал цель: на кухонном фото 1200×900 четыре одинаковых белых стула, слой разметки обводит передний левый, а промпт называет только «стул внутри красного круга» и просит перекрасить его в горчично-жёлтый, оставив остальные белыми. Каждую ячейку запускали по одному разу.

Примечание: laozhang.ai — наш собственный сервис; его цены — наши тарифы, а не независимое сравнение.

МаршрутСлой разметкиРазмер ответаКакой стул стал жёлтымВремя
gpt-image-2.6-webесть1448×1086передний правый (не тот)24 с
gpt-image-2.6-webнет1448×1086стулья справа (не те)24 с
gpt-image-2.6-sunburst-vip, size: "1536x1152"есть1536×1152передний правый (не тот)38 с
gpt-image-2.6-sunburst-vip, size: "1536x1152"нет1536×1152передний правый (не тот)38 с

Обведённый стул во всех четырёх случаях остался белым, красного круга ни в одном ответе не было. Первый раунд с вазой из примера OpenAI этого не показал бы: вазу на столе модель перекрашивала и без разметки, и с расплывчатым «Make the vase blue.», потому что её легко найти по одному тексту. В том же раунде VIP-маршрут принял слой неверного размера (1000×750) и непрозрачный слой с ответом 200 и без единой ошибки. Отсюда практическое правило: чтобы проверить, читает ли маршрут разметку, обведите один из нескольких одинаковых предметов и сравните ответ с разметкой и без неё.

Тест маршрутов web и sunburst-vip со слоем и без: во всех четырёх случаях жёлтым стал не обведённый стул

Квадратный результат вместо исходного кадра — отдельная ловушка VIP-маршрута. Без параметра size он возвращал 2048×2048 и перекомпоновывал кухню 4:3 в квадрат, а с явным size: "1536x1152" сохранил 4:3. Маршрут gpt-image-2.6-web с разметкой отдал 1448×1086, тот же размер, что и опубликованные результаты OpenAI для этого фото с size="auto".

Для разметки через LaoZhang нужен официальный проброс: модели gpt-image-2.6-flare и gpt-image-2.6-sunburst в группе OpenAI Official (или OpenAI Official Enterprise с наценкой 20 %), оплата по токенным ценам OpenAI. По документации LaoZhang API по GPT Image тело запроса там такое же, как у официального API, меняется только model; в Python это OpenAI(base_url="https://api.laozhang.ai/v1", api_key=...) с ключом из этой группы. О markup документация не пишет, и отдельного прогона разметки через официальный проброс 5 ноября 2026 года не было, поэтому перед рабочей нагрузкой проверьте его тестом с одинаковыми предметами. Поштучные маршруты стоят $0,03 за вызов, правки включены, но для разметки они, судя по тесту выше, не годятся.

Сама разметка ничего не добавляет к цене. По руководству OpenAI правки с разметкой считаются по тем же токенным тарифам, что и остальные правки; у GPT Image 2.6 это $8 за 1 млн входных токенов изображения, $30 за 1 млн выходных и $5 за 1 млн входных текстовых. Для ориентира: одна обычная правка без разметки на Sunburst с quality: "low" через официальный проброс LaoZhang в замере команды документации LaoZhang обошлась в $0,03301.

Как проверить, что правка осталась внутри круга

Модель не вклеивает изменение в старые пиксели, а перерисовывает изображение целиком, поэтому разница с оригиналом за пределами пометки никогда не равна нулю. Вопрос в том, насколько она велика. OpenAI в примере с вазой сама советует сравнить остальную часть каждого изображения с оригиналом, и это можно сделать числом:

  1. Возьмите исходное фото и тот же слой разметки, что отправляли.
  2. Запустите скрипт ниже: он уменьшает результат до размера оригинала, закрашивает эллипс по границам пометки и выводит среднюю разницу пикселей внутри и снаружи в процентах от полной шкалы.
  3. Сравните два числа: внутри круга разница должна быть заметно больше, чем снаружи.
  4. Посмотрите глазами на то, что важно за кругом (лица, надписи, края мебели), и убедитесь, что красного круга в результате нет.
  5. Если снаружи изменилось много, повторите с complexity: "low" и явным «keep the rest unchanged» в промпте или попробуйте gpt-image-2.6-sunburst на medium или high.
python
"""Сравнивает результат правки с оригиналом внутри и снаружи пометки.
Использование: python3 check_edit_area.py photo.png markup.png result.png"""
import sys
import numpy as np
from PIL import Image, ImageDraw, ImageOps

photo_path, markup_path, result_path = sys.argv[1:4]
orig = ImageOps.exif_transpose(Image.open(photo_path)).convert("RGB")
alpha = np.array(Image.open(markup_path).convert("RGBA"))[:, :, 3]
ys, xs = np.nonzero(alpha > 0)                      # непрозрачные пиксели пометки
region = Image.new("L", orig.size, 0)
ImageDraw.Draw(region).ellipse([xs.min(), ys.min(), xs.max(), ys.max()], fill=255)
inside = np.array(region) > 0                       # закрашенный круг пометки

result = Image.open(result_path).convert("RGB")
print("размер результата:", result.size, "оригинал:", orig.size)
a = np.array(orig).astype(float)
b = np.array(result.resize(orig.size, Image.LANCZOS)).astype(float)
diff = np.abs(b - a).mean(axis=2) / 255 * 100       # средняя разница, % от полной шкалы
print(f"внутри пометки: {diff[inside].mean():.1f} %")
print(f"снаружи:        {diff[~inside].mean():.1f} %")

Скрипт рассчитан на одну пометку: при нескольких кругах или свободном наброске он берёт эллипс, вписанный в общий прямоугольник всех пометок, и тогда «внутри» окажется больше, чем вы обвели.

Ориентиры дают опубликованные OpenAI результаты примера с вазой, разобранные этим способом 5 ноября 2026 года. Оба ответа пришли размером 1448×1086 при входе 1200×900. Внутри круга изменилось 12,1 % у Sunburst и 11,2 % у Flare, снаружи — 4,3 % у Sunburst и 8,4 % у Flare, то есть в этом примере Flare изменил остальную кухню примерно вдвое сильнее. Собственный контрольный расчёт блога 5 ноября 2026 года показывает, сколько из этого шум масштабирования: если исходное фото 1200×900 увеличить до 1448×1086 и вернуть обратно фильтром LANCZOS, тот же скрипт даёт около 0,3 % снаружи, так что почти вся разница — работа модели. Это один пример, а не рейтинг моделей; OpenAI отдельно пишет, что Sunburst стабильнее от правки к правке на medium и high.

Markup и GPT Image 2.5: что пишут руководство и справочник OpenAI

Документы OpenAI по состоянию на 5 ноября 2026 года расходятся в том, каким моделям доступна разметка. Руководство по генерации изображений говорит о правках с разметкой для «supported GPT Image 2.5 and 2.6 models», а справочник по методу images.edit в описании поля markup пишет только «Supports GPT Image 2.5». Анонс Images 2.6, где разметка «comes to the API», и пример в руководстве с gpt-image-2.6-flare говорят в пользу 2.6, поэтому на 2.6 разметку можно отправлять. GPT Image 2.5 называют оба документа, хотя руководство пишет о «поддерживаемых» моделях 2.5 и списка не даёт.

Многие страницы, где разметку называют функцией GPT Image 2.5, написаны до 4 ноября 2026 года, когда у 2.6 ещё не было ID модели в API; теперь они есть — gpt-image-2.6-flare и gpt-image-2.6-sunburst. Стоит ли переводить на 2.6 остальные задачи и сколько это стоит по уровням качества, разобрано в статье GPT Image 2.6: отличия от 2.5 — GIF, SVG и low в 4 раза дороже.

Источники2

Внешние страницы, на которые ссылается это руководство, в порядке упоминания. Последнее обновление: 5 нояб. 2026 г..

  1. 1.руководству OpenAI по генерации изображений, раздел Guide an edit with markupdevelopers.openai.com/api/docs/guides/image-generation
  2. 2.справочнику OpenAI по методу images.editdevelopers.openai.com/api/reference/resources/images/methods/edit
Иллюстрация ChatGPT Images 2.5: создание картинки в диалоге, выбор модели в API и готовый файл
Руководства по API

ChatGPT Images 2.5: как пользоваться и где выбрать Sunburst или Flare

В ChatGPT Images 2.5 можно создавать и редактировать изображения прямо в диалоге. Объясняем, как начать работу, где выбрать Flare или Sunburst в API и почему по картинке в чате нельзя достоверно определить модель.

7 мин
Обложка «GPT Image 2.5: Sunburst или Flare?»: слева наброски и чек-лист повседневных задач, справа настольная лампа с увеличенными деталями под надписью «Точность правок»
Руководства по API

GPT Image 2.5 Flare или Sunburst: скорость, правки и цена

Начинайте с Flare: в сторонних замерах он на 25–45 % быстрее. Sunburst — для правок, где Flare не справился. При равных quality и size попытка стоит одинаково.

12 мин