GPT Image 2.6 마크업 편집 API 사용법: 오버레이 검사와 경로별 실측
GPT Image 2.6 마크업은 원본과 같은 크기의 투명 PNG를 markup 필드로 보냅니다. 2026년 11월 5일 테스트에서 건별 과금 중계 경로는 이를 반영하지 않았습니다.
목차

GPT Image 2.6의 마크업은 HTML 마크업이 아니라 OpenAI 이미지 편집 API의 기능입니다. 원본 사진 위에 동그라미나 스케치를 그린 별도의 투명 PNG 오버레이를 만들어 POST /v1/images/edits의 markup 필드로 보내면, 모델은 오버레이에서 고칠 위치를 보고 prompt에서 무엇으로 바꿀지를 읽습니다. 2026년 11월 4일 출시된 gpt-image-2.6-flare와 gpt-image-2.6-sunburst에서 쓸 수 있고, 오버레이는 EXIF 방향을 적용한 뒤의 원본과 가로·세로가 같아야 하며 투명 픽셀을 포함해야 합니다.
보내는 형태는 두 가지입니다. multipart 요청이면 image에 원본, markup에 오버레이 파일을 올리고, JSON 요청이면 원본은 images 배열에 넣고 오버레이는 "markup": {"image_url": ...} 또는 "markup": {"file_id": ...} 중 하나로 지정합니다. 오버레이는 첫 번째 입력 이미지에만 적용되고, mask나 prompt_rewriter와는 함께 쓸 수 없습니다.
어느 경로로 보내는지가 결과를 가릅니다. 2026년 11월 5일 LaoZhang API의 건별 과금 경로(gpt-image-2.6-web, gpt-image-2.6-sunburst-vip)에서 테스트했을 때는 오버레이를 보내든 안 보내든 결과가 같았고, 동그라미로 표시한 의자는 한 번도 바뀌지 않았습니다. 응답은 모두 200이었으므로 성공 응답만으로 마크업이 적용됐다고 판단할 수 없습니다. 마크업은 OpenAI API에 직접 보내거나, OpenAI와 같은 요청 본문을 받는 LaoZhang 공식 포워딩 경로로 보내세요. 다만 2026년 11월 5일 기준 공식 포워딩 경로에서는 마크업을 아직 실행해 보지 않았으므로 오버레이가 반영된다고 단정할 수 없고, 어느 경로든 아래의 의자 테스트 방식으로 한 번 확인한 뒤 실제 작업에 쓰세요.
안내: laozhang.ai는 이 블로그 운영팀의 자사 서비스입니다. 그 가격은 독립적인 비교가 아니라 자사 제시 가격입니다.
GPT Image 2.6 마크업이 하는 일: 위치는 오버레이, 내용은 prompt
마크업 오버레이는 "어디를"만 알려 주고, "무엇으로 바꿀지"는 여전히 prompt가 정합니다. OpenAI 이미지 생성 가이드의 마크업 편집 절은 주석 레이어로 변경 위치를 보여 주고 원하는 변경과 유지할 부분은 프롬프트에 쓰라고 안내합니다. 그래서 오버레이에 "파란색" 같은 글자를 적어 넣기보다, 프롬프트에 대상과 변경 내용, 유지할 것, 그리고 완성본에서 빨간 원을 지우라는 지시까지 함께 쓰는 편이 맞습니다.
OpenAI 예제의 프롬프트가 이 구조를 그대로 보여 줍니다. "Recolor the striped vase inside the red circle to solid cobalt blue ceramic. Keep its shape, the dried stems, and the rest of the kitchen unchanged. Remove the red circle from the finished photo." 원 안의 대상을 원 자체로 가리키고, 바꿀 색과 재질, 유지할 줄기와 주방, 원 제거를 한 문장씩 나눠 적었습니다. 입력 이미지를 여러 장 보내면 오버레이는 첫 번째 이미지에만 적용되고 나머지는 참고 이미지로 쓰입니다.
GPT Image 2.6이 아직 출시되지 않았고 모델 ID도 없다고 적힌 글은 11월 4일 출시 전에 쓰인 것이며, 지금은 위의 두 모델 ID로 API를 호출할 수 있습니다. ChatGPT 앱 편집기에도 마크업 도구가 있지만 버튼을 눌러도 이미지 전체를 새로 그리는 다른 기능이라 챗GPT 이미지 편집: 일부만 고쳐도 전체가 바뀌는 이유와 부분 수정법에서 따로 다룹니다. 2.5에서 2.6으로 바꿀지는 품질 단계별 비용이 기준이 되므로 GPT Image 2.6 vs 2.5 차이: high부터 같은 값, low·medium은 3~4배를 참고하세요.
마크업 오버레이 파일 조건: 같은 크기, 투명 픽셀, 16,777,216픽셀 이하
오버레이가 지켜야 할 조건은 OpenAI 가이드와 OpenAI API 레퍼런스의 images.edit 항목에 나뉘어 적혀 있습니다. 2026년 11월 5일 기준으로 정리하면 아래와 같고, 오른쪽 열은 다음 절의 스크립트가 각 조건을 확인하는 방법입니다.
| 조건 | OpenAI 문서 기준 | 로컬에서 확인하는 방법 |
|---|---|---|
| 가로·세로 | EXIF 방향을 적용한 뒤 첫 번째 입력 이미지와 같아야 함 | ImageOps.exif_transpose로 돌린 원본 크기와 비교 |
| 투명 픽셀 | 투명 픽셀을 포함해야 하고, 원본에 합친(flatten) 이미지는 안 됨 | RGBA 모드이고 알파 최솟값이 255보다 작은지 확인 |
| 픽셀 수 | 첫 번째 이미지와 오버레이 각각 16,777,216픽셀 이하 | 가로×세로 계산 |
| 파일 용량 | 오버레이 파일 50MB 이하 | 파일 크기 확인 |
JSON의 image_url 길이 | 레퍼런스상 최대 20,971,520자(HTTPS URL 또는 base64 data URL) | base64 문자열 길이 확인. 큰 파일은 multipart나 file_id로 |
| 함께 쓸 수 없는 파라미터 | mask, prompt_rewriter | 요청 코드에서 두 필드를 제거 |
16,777,216픽셀은 4096×4096과 같은 값이라 일반적인 사진은 대부분 여유가 있습니다. 실수가 잦은 조건은 오히려 방향입니다. 휴대폰 사진은 픽셀을 가로로 저장하고 EXIF 태그로 세로 표시를 지시하는 경우가 많은데, 방향을 적용하면 가로·세로가 뒤바뀌므로 파일에 기록된 크기로 오버레이를 만들면 조건을 어기게 됩니다.
로컬 검사를 건너뛰면 안 되는 이유도 있습니다. 2026년 11월 5일 건별 과금 VIP 경로는 1000×750으로 크기가 틀린 오버레이와 흰 배경에 합친 불투명 오버레이를 모두 오류 없이 200으로 받았습니다. 경로가 잘못된 파일을 걸러 준다고 기대할 수 없으니, 보내기 전에 직접 확인해야 합니다.
Python으로 마크업 오버레이 만들고 검사하기
아래 make_markup_overlay.py는 Pillow만으로 오버레이를 만들고 앞 절의 조건을 검사하는 스크립트입니다. 원본에 EXIF 방향을 먼저 적용하고, 같은 크기의 완전히 투명한 캔버스에 빨간 타원 하나를 그린 뒤, 크기 일치·투명 픽셀·픽셀 수·파일 용량을 확인합니다. 좌표 x0 y0 x1 y1은 타원을 감싸는 사각형의 왼쪽 위와 오른쪽 아래이며, 방향을 적용한 사진 기준의 픽셀 값입니다.
"""GPT Image 2.6 / 2.5 편집용 마크업 오버레이를 만들고 검사합니다.
EXIF 방향을 적용한 원본과 같은 크기의 투명 캔버스에 빨간 타원을 그린 뒤,
OpenAI가 밝힌 조건(같은 가로·세로, 투명 픽셀 포함, 16,777,216픽셀 이하, 50MB 이하)을 확인합니다.
사용법: 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))pip install pillow로 Pillow를 설치한 뒤 OpenAI 예제의 1200×900 주방 사진(PNG로 변환)에 실행하면 다음과 같이 출력됩니다. 2026년 11월 5일 실행 결과이며, 오버레이 파일은 5,645바이트였습니다.
$ python3 make_markup_overlay.py kitchen.png 235 610 465 785 markup.png
photo 1200x900 -> markup.png (5645 bytes)
OK같은 날 check()에 일부러 잘못 만든 오버레이 두 개와 OpenAI가 공개한 예제 오버레이를 넣어 봤습니다. 1000×750 오버레이는 size (1000, 750) != photo (1200, 900), 흰 배경에 합친 오버레이는 no transparent pixels (flattened overlay)로 걸렸고, OpenAI의 오버레이는 통과했습니다. 이 스크립트는 OpenAI 문서에 적힌 규칙을 로컬에서 검사할 뿐이며, 규칙을 어긴 파일을 공식 API가 어떻게 처리하는지는 알려 주지 않습니다.
이미지 편집 도구에서 직접 그린 오버레이라면 원본과 같은 캔버스 크기로 투명 배경을 유지한 채 PNG로 내보낸 뒤, 그리기 부분은 건너뛰고 check()만 호출하면 됩니다.
python3 -c "from make_markup_overlay import check; print(check('photo.jpg', 'my-overlay.png') or 'OK')"multipart와 JSON으로 markup을 보내는 순서
요청은 원본, 오버레이, 프롬프트 세 가지를 한 번에 /v1/images/edits로 보내는 구조이고, 나머지 파라미터는 일반 편집과 같습니다. 다만 마크업을 쓸 때 빼야 하는 필드와 부분 수정에 맞는 설정이 있어 순서대로 정리합니다.
- 원본을 첫 번째 입력 이미지로 둡니다. multipart는
image필드, JSON은images배열의 첫 항목입니다. - 앞 절의 스크립트로 만든 오버레이가
OK인지 확인합니다. - 오버레이를
markup으로 첨부합니다. multipart는 파일 업로드, JSON은image_url(HTTPS URL 또는 base64 data URL)과file_id중 정확히 하나를 담은 객체입니다. prompt에 "빨간 원 안의 대상", 바꿀 내용, 유지할 것, 원 제거를 씁니다. 편집 지시문을 다듬는 방법은 GPT Image 2.6 프롬프트 작성 가이드에서 다룹니다.mask,prompt_rewriter,input_fidelity는 넣지 않습니다. 한 부분만 고치는 편집이면complexity는low부터 시작합니다.- 결과를 받으면 출력 크기와 동그라미 바깥의 변화를 확인합니다(아래 "동그라미 바깥" 절).
5번의 근거는 모두 OpenAI 문서입니다. 프롬프트 가이드는 마크업을 보낼 때 mask와 prompt_rewriter를 생략하고, 이미지 편집에서는 input_fidelity를 생략하라고 적고 있습니다. complexity는 2.6에서 새로 생긴 파라미터로, OpenAI의 Images 2.6 발표는 대부분의 편집에 low를 권하고 요소가 많은 장면에서만 medium이나 high를 써 보라고 합니다. LaoZhang API 문서는 이 파라미터의 기본값을 high로 적고 있어, 부분 수정이라면 값을 직접 지정하는 편이 안전합니다.
안내: laozhang.ai는 이 블로그 운영팀의 자사 서비스입니다. 그 가격은 독립적인 비교가 아니라 자사 제시 가격입니다.
multipart는 OpenAI Python SDK로 보내는 방법이 가장 간단합니다. 아래 코드는 OpenAI 가이드 예제와 같은 형태이고, 경로에 따라 base_url과 키만 바뀝니다. SDK 버전이 오래돼 markup 인자를 받지 않으면 SDK를 업데이트하거나 그 아래의 curl 형태로 보내세요.
import base64
from pathlib import Path
from openai import OpenAI
client = OpenAI() # OpenAI 직접: 환경 변수 OPENAI_API_KEY 사용
# LaoZhang 공식 포워딩: OpenAI Official 그룹 토큰으로
# client = OpenAI(base_url="https://api.laozhang.ai/v1", api_key="sk-...")
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"),
quality="medium",
prompt=(
"Recolor the striped vase inside the red circle to solid cobalt blue ceramic. "
"Keep its shape, the dried stems, and the rest of the kitchen unchanged. "
"Remove the red circle from the finished photo."
),
)
Path("edited.png").write_bytes(base64.b64decode(result.data[0].b64_json))curl로 보낼 때는 -F로 두 파일을 올립니다.
curl --fail --silent --show-error https://api.openai.com/v1/images/edits \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-F model=gpt-image-2.6-flare \
-F quality=medium \
-F 'image=@kitchen.png;type=image/png' \
-F 'markup=@markup.png;type=image/png' \
-F 'prompt=Recolor the striped vase inside the red circle to solid cobalt blue ceramic. Keep its shape, the dried stems, and the rest of the kitchen unchanged. Remove the red circle from the finished photo.' |
jq -er '.data[0].b64_json' | base64 --decode > edited.png원본이 이미 웹에 올라가 있거나 파일 업로드를 다루기 번거로운 환경이라면 JSON 요청이 편합니다. 원본은 images 배열에 HTTPS URL로, 오버레이는 base64 data URL로 넣는 예시입니다. 위 예제의 5,645바이트 오버레이는 data URL로 바꿔도 몇 KB에 불과하지만, 사진을 그대로 담은 큰 PNG라면 image_url 길이 제한에 걸릴 수 있으므로 Files API로 올려 file_id를 쓰세요.
import base64, os, requests
def data_url(path):
with open(path, "rb") as f:
return "data:image/png;base64," + base64.b64encode(f.read()).decode()
body = {
"model": "gpt-image-2.6-sunburst",
"images": [{"image_url": "https://example.com/kitchen.png"}], # 첫 번째 이미지에 오버레이 적용
"markup": {"image_url": data_url("markup.png")}, # image_url과 file_id 중 하나만
"prompt": "Recolor the striped vase inside the red circle to solid cobalt blue ceramic. "
"Keep its shape, the dried stems, and the rest of the kitchen unchanged. "
"Remove the red circle from the finished photo.",
"quality": "medium",
"complexity": "low",
}
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()
open("edited.png", "wb").write(base64.b64decode(r.json()["data"][0]["b64_json"]))마크업·마스크·텍스트만 비교: 같은 물건이 여러 개면 마크업
말로 하나를 정확히 가리킬 수 있으면 텍스트만으로 충분하고, 같은 물건이 여러 개이거나 위치를 말로 설명하기 어려우면 마크업을 씁니다. 마스크는 이름이 비슷하지만 다른 파라미터이고 규칙도 다르며, 마크업과 한 요청에 함께 넣을 수 없습니다. 2026년 11월 5일 기준 OpenAI 가이드의 설명으로 세 방법을 나란히 놓으면 다음과 같습니다.
| 기준 | 마크업 (markup) | 마스크 (mask) | 텍스트만 (prompt) |
|---|---|---|---|
| 표시하는 것 | 동그라미·스케치로 바꿀 위치 | 알파 채널로 편집할 영역 | 말로 대상을 지정 |
| 쓸 수 있는 API | Image API /v1/images/edits | Image API 편집, Responses API의 영역 편집 | 둘 다 |
| 파일 조건 | 투명 PNG, 방향 적용 후 원본과 같은 크기, 투명 픽셀 포함 | 알파 채널, 원본과 같은 형식·크기, 50MB 미만 | 없음 |
| 정밀도 | 위치를 가리키는 표시. 바뀐 범위는 결과를 원본과 비교해 확인 | 프롬프트 기반이라 마스크 모양을 정확히 따르지 않을 수 있음 | 대상이 하나로 특정될 때만 정확 |
| 함께 쓸 수 없는 것 | mask, prompt_rewriter | markup | 해당 없음 |
| 맞는 상황 | 같은 의자 네 개 중 하나, 말로 설명하기 어려운 위치 | Responses API로 영역 편집을 할 때, 편집 영역의 모양을 지정하고 싶을 때 | 꽃병처럼 이름만으로 찾을 수 있는 대상 |
마스크도 픽셀 단위로 영역을 고정하는 도구는 아닙니다. OpenAI 가이드는 GPT Image의 마스크 편집이 전적으로 프롬프트 기반이며, 모델이 마스크를 참고하지만 모양을 완벽하게 따르지는 않을 수 있다고 설명합니다. 따라서 세 방법 모두 결과를 원본과 비교하는 단계가 필요합니다.
텍스트만으로 충분한 경우와 마크업이 필요한 경우의 차이는 테스트에서도 드러났습니다. 주방 사진의 줄무늬 꽃병은 식탁 위에 하나뿐이라, 오버레이 없이 보낸 요청에서도 "Make the vase blue."라는 짧은 지시에서도 파랗게 바뀌었습니다. 반면 똑같은 흰 의자 네 개 중 하나를 고르는 작업은 말만으로는 어느 의자인지 정할 수 없어서, 오버레이가 실제로 읽혔는지를 가리는 시험이 됩니다.
건별 과금 경로 실측: 동그라미 친 의자는 네 번 모두 그대로
2026년 11월 5일 LaoZhang API의 건별 과금 경로 두 곳에서 마크업이 반영되는지 시험했습니다. 원본은 OpenAI 예제의 1200×900 주방 사진이고, 오버레이는 똑같은 흰 의자 네 개 중 왼쪽 앞 의자만 빨간 타원으로 둘렀습니다(좌표 235, 610, 465, 785). 프롬프트는 의자를 위치로 설명하지 않고 "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."라고만 적었습니다. 오버레이를 읽는다면 왼쪽 앞 의자가, 읽지 않는다면 모델이 고른 아무 의자가 노랗게 바뀌는 설계입니다.
안내: 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초 |
네 번 모두 동그라미 친 왼쪽 앞 의자는 흰색 그대로였고, 빨간 원은 어느 결과에도 남지 않았습니다. 마크업을 넣은 요청과 뺀 요청의 결과가 같은 방향으로 틀렸으므로, 이 두 경로에서는 오버레이가 눈에 보이는 차이를 만들지 못했다고 보는 것이 맞습니다. 조건마다 1회씩 실행한 결과이고, OpenAI API 자체나 LaoZhang 공식 포워딩 경로에 대해서는 아무것도 말해 주지 않습니다.

이 의자 테스트를 따로 설계한 이유는 같은 날 앞서 진행한 꽃병 테스트가 판단을 내려 주지 못했기 때문입니다. VIP 경로에서 마크업 있음, 마크업 없음, 짧은 지시, 엄격한 지시, 크기가 틀린 오버레이, 불투명 오버레이까지 모두 200이 돌아왔고 꽃병은 전부 파랗게 바뀌었습니다. 꽃병은 글만으로도 찾을 수 있는 대상이라 결과가 맞아도 오버레이를 읽었다는 증거가 되지 않았습니다. 자기 경로에서 마크업을 확인할 때도 같은 원리가 통합니다. 똑같은 물건 여러 개 중 하나에만 동그라미를 치고, 같은 요청을 오버레이 없이 한 번 더 보내 두 결과를 비교하세요.
마크업을 보낼 경로: OpenAI API 직접 또는 공식 포워딩
마크업이 필요한 편집은 OpenAI API에 직접 보내거나, 요청 본문을 OpenAI와 같은 형태로 전달하는 공식 포워딩 경로로 보내는 것이 현재로서는 근거가 있는 선택입니다. OpenAI는 가이드와 프롬프트 가이드에서 이 기능을 자사 /v1/images/edits 기준으로 설명하고, 두 모델의 예제 결과까지 공개하고 있습니다.
LaoZhang API에서 마크업을 시도하려면 공식 포워딩 경로를 쓰세요. LaoZhang API의 GPT Image 2.5·2.6 문서에 따르면 OpenAI Official 그룹(또는 20%가 붙는 OpenAI Official Enterprise 그룹) 토큰으로 gpt-image-2.6-flare나 gpt-image-2.6-sunburst를 호출하면 OpenAI 토큰 가격으로 과금되고, 요청 본문은 공식과 같아 model만 바꾸면 됩니다. 라우팅과 과금은 토큰의 그룹이 정하므로, default 그룹 토큰으로 같은 모델 이름을 보내도 이 경로로 가지 않습니다. 이 문서는 markup을 따로 언급하지 않고, 2026년 11월 5일 기준 이 경로에서 마크업을 직접 실행해 본 결과는 아직 없으므로 앞 절의 의자 방식으로 한 번 확인한 뒤 쓰세요.
안내: laozhang.ai는 이 블로그 운영팀의 자사 서비스입니다. 그 가격은 독립적인 비교가 아니라 자사 제시 가격입니다.
장당 $0.03인 건별 과금 경로 가운데 테스트한 gpt-image-2.6-web과 gpt-image-2.6-sunburst-vip는 오버레이를 반영하지 않았고, 같은 VIP 계열의 gpt-image-2.6-flare-vip는 따로 시험하지 않았습니다. 이 경로들은 꽃병처럼 글로 특정할 수 있는 대상을 고치는 텍스트 편집에는 쓸 수 있지만, 마크업이 필요한 작업의 경로로는 맞지 않습니다.
편집 결과가 정사각형으로 나올 때: size를 원본 비율로 지정
4:3 사진을 편집했는데 정사각형으로 돌아오고 방 구도가 다시 짜였다면 size를 확인하세요. 2026년 11월 5일 VIP 경로에서 size를 빼고 1200×900 주방 사진을 편집하자 결과가 모두 2048×2048로 나왔고, 정사각형에 맞춰 방이 재구성됐습니다. size: "1536x1152"를 지정하자 4:3 구도가 유지됐습니다.
OpenAI 예제는 size="auto"로 1448×1086을 받아 4:3 비율을 지키면서 크기만 키웠고, LaoZhang web 경로도 같은 사진에서 1448×1086을 돌려줬습니다. 비율이 자동으로 유지되지 않는 경로라면 원본과 같은 비율의 크기를 직접 지정하고, 결과를 받으면 비교하기 전에 출력 크기부터 확인하세요. 구도가 바뀐 결과는 픽셀 비교 이전에 이미 실패입니다.
동그라미 바깥이 바뀌지 않았는지 확인하는 방법
OpenAI 프롬프트 가이드는 마크업 예제 끝에서 "Compare the rest of each image with the original"이라며 나머지 영역에 다른 변화가 없는지 비교하라고 권합니다. 눈으로 훑으면 얼굴의 미세한 변화나 글자 한 획은 놓치기 쉬우므로, 동그라미 안과 바깥의 변화율을 숫자로 재고 차이 지도를 함께 보는 방법을 씁니다.
- 결과 이미지의 가로·세로 비율이 원본과 같은지 확인합니다. 다르면 앞 절의
size문제부터 고칩니다. - 아래
compare_edit.py로 동그라미 안과 바깥의 평균 변화율을 냅니다. - 함께 저장되는
diff.png를 열어, 밝게 표시된 곳이 동그라미 바깥에 있는지 봅니다. 사람 얼굴, 글자, 로고, 제품 라벨이 있으면 그 부분을 먼저 확인합니다. - 바깥 변화가 크면 프롬프트에 유지할 대상을 구체적으로 더 적고,
complexity는low로 둔 채 Sunburst를qualitymedium이나high로 다시 시도합니다.
"""원본·오버레이·편집 결과를 비교해 동그라미 안과 바깥의 평균 변화율을 출력합니다.
사용법: python3 compare_edit.py 원본.png 오버레이.png 결과.png [diff.png]"""
import sys
import numpy as np
from PIL import Image, ImageDraw, ImageOps
orig_path, overlay_path, edited_path = sys.argv[1:4]
orig = ImageOps.exif_transpose(Image.open(orig_path)).convert("RGB")
alpha = np.array(Image.open(overlay_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 # 동그라미 안을 채운 영역
edited = Image.open(edited_path).convert("RGB")
print("결과 크기:", edited.size, "/ 원본:", orig.size)
a = np.array(edited.resize(orig.size, Image.LANCZOS)).astype(float)
o = np.array(orig).astype(float)
diff = np.abs(a - o).mean(axis=2) / 255 * 100 # 픽셀별 변화율(%)
print(f"동그라미 안 {diff[inside].mean():.1f}% / 바깥 {diff[~inside].mean():.1f}%")
if len(sys.argv) > 4: # 어디가 바뀌었는지 눈으로 볼 차이 지도
Image.fromarray(np.clip(diff * 4, 0, 255).astype("uint8")).save(sys.argv[4])이 방식으로 2026년 11월 5일 OpenAI가 공개한 꽃병 예제의 결과 두 장을 원본과 비교했습니다. 두 결과 모두 1448×1086이어서 1200×900으로 줄여 비교했고, 동그라미 안의 평균 변화는 Sunburst 12.1%, Flare 11.2%로 비슷했지만 바깥은 Sunburst 4.3%, Flare 8.4%로 Flare가 나머지 주방을 약 두 배 더 바꿨습니다. 같은 날 리사이즈만으로 생기는 차이도 따로 쟀습니다. 원본을 LANCZOS 방식으로 1448×1086까지 키운 뒤 같은 스크립트로 1200×900으로 되돌려 비교하자 바깥 변화는 0.3%였으므로, 두 결과의 바깥 변화 대부분은 모델이 사진을 다시 그리면서 생긴 차이입니다.

이 숫자는 예제 하나에서 나온 관찰이라 모델 순위로 읽으면 안 됩니다. 다만 OpenAI가 Sunburst를 medium이나 high 품질에서 편집 간 일관성이 더 높은 모델로 소개하고 있고 이 예제도 medium이었으므로, 바깥을 최대한 건드리지 않아야 하는 편집이라면 Sunburst부터 비교해 볼 근거는 됩니다. 정해진 합격 기준은 없으니, 같은 사진에서 동그라미 안 변화가 바깥보다 분명히 크고 차이 지도의 밝은 부분이 동그라미 안에 모여 있는지를 기준으로 판단하세요.
GPT Image 2.6 마크업 편집 API 자주 묻는 질문
마크업을 쓰면 요금이 더 나오나요?
추가 요금은 없습니다. OpenAI 가이드는 마크업 편집이 다른 편집과 같은 토큰 단가를 쓰며 별도 요금이 없다고 밝히고 있고, 2026년 11월 5일 기준 OpenAI API 가격 페이지의 GPT Image 2.6 단가는 100만 토큰당 텍스트 입력 $5, 이미지 입력 $8, 이미지 출력 $30입니다. 참고로 LaoZhang 문서 팀이 같은 날 공식 포워딩 경로에서 측정한 Sunburst low 일반 편집 1건의 비용은 $0.03301이었습니다.
GPT Image 2.5에서도 markup을 쓸 수 있나요?
OpenAI 문서끼리 표기가 다릅니다. 2026년 11월 5일 기준 이미지 생성 가이드는 마크업 편집을 "supported GPT Image 2.5 and 2.6 models"에서 쓸 수 있다고 적고, 출시 발표와 모델 페이지도 2.6을 대상으로 설명합니다. 반면 API 레퍼런스의 markup 항목에는 "Supports GPT Image 2.5"라고만 적혀 있습니다. 2.5로 마크업 편집을 하려면 실제 작업에 쓰기 전에, 똑같은 물건 여러 개 중 하나에만 동그라미를 치고 같은 요청을 오버레이 있이 한 번, 없이 한 번 보내 결과를 비교해 보세요.
참고 자료4
이 글이 링크한 외부 페이지를 본문에 나온 순서대로 정리했습니다. 마지막 업데이트: 2026년 11월 5일.
참고 자료4
이 글이 링크한 외부 페이지를 본문에 나온 순서대로 정리했습니다. 마지막 업데이트: 2026년 11월 5일.
- 1.OpenAI 이미지 생성 가이드의 마크업 편집 절developers.openai.com/api/docs/guides/image-generation
- 2.OpenAI API 레퍼런스의 images.edit 항목developers.openai.com/api/reference/resources/images/methods/edit
- 3.OpenAI의 Images 2.6 발표openai.com/index/introducing-images-2-6
- 4.OpenAI API 가격 페이지developers.openai.com/api/docs/pricing





