gpt-image-2로 투명 이미지를 받으려면 background="transparent"와 output_format="png" 또는 "webp"를 함께 지정해야 합니다. 2026년 9월 8일 기준 OpenAI는 이 기능을 프리뷰로 안내합니다. JPEG는 투명 배경을 지원하지 않습니다. OpenAI 출력 설정 문서
상품 이미지나 앱 아이콘을 만들 때는 여기서 한 단계 더 확인해야 합니다. PNG 파일에도 흰 배경이 그대로 들어갈 수 있고, RGBA 이미지라도 모든 픽셀이 불투명할 수 있습니다. 요청한 형식으로 응답을 저장한 다음 파일의 실제 형식과 알파값을 검사하면, 생성 문제와 저장·변환 문제를 구분할 수 있습니다.
대화창에서 요청한 경우와 API를 호출한 경우를 구분하세요
“투명 배경으로 만들어 줘”라고 입력한 대화창과 코드에서 background="transparent"를 보낸 요청은 확인 방법이 다릅니다. 아래 코드는 OpenAI Images API 기준입니다. 공식 API에서 지원하는 옵션이 ChatGPT 화면이나 다른 이미지 서비스에 그대로 노출된다는 뜻은 아닙니다.
대화창에서는 피사체만 남기고 배경을 투명하게 만들어 달라고 요청한 뒤, 제공되는 다운로드 기능으로 결과 파일을 저장하세요. 화면을 캡처하면 대화창의 바탕색까지 함께 저장될 수 있어 원본 투명도를 확인할 수 없습니다. 내려받은 파일의 형식과 알파값을 아래 방법으로 검사하면 됩니다.
API에서 background가 지원되지 않는다는 오류를 받았다면 요청 URL, 모델 ID, 오류 본문부터 확인하세요. 공식 문서의 현재 지원 조건과, 사용 중인 서비스가 그 옵션을 전달하는지는 별개의 문제입니다. 오래된 실패 사례만으로 현재 모델 전체가 투명 배경을 지원하지 않는다고 결론 내리거나, 한 중계 서비스의 거절을 모든 API에 적용하면 원인을 놓치기 쉽습니다.
PNG와 WebP 중 어떤 형식을 요청할까요?
두 형식 모두 투명도를 담을 수 있습니다. 선택 기준은 투명도 지원 여부보다 후속 편집 도구와 전달 방식입니다.
| 필요한 작업 | 요청할 형식 | 설정할 내용 |
|---|---|---|
| PNG를 요구하는 디자인 도구나 업로드 양식에 전달 | png | background="transparent", output_compression 생략 |
| WebP를 지원하는 웹·앱에 직접 전달 | webp | background="transparent", 필요할 때만 output_compression 추가 |
| 투명 원본을 남기면서 웹용 파일을 따로 제작 | 원본 png, 전달본 webp | 변환 전후 파일을 각각 검사 |
PNG는 기본 출력 형식이지만, 저장 코드와 요청이 어긋나지 않도록 예제에서는 명시합니다. 공식 프롬프트 가이드는 PNG에서 output_compression을 생략하도록 안내합니다. WebP에서는 이 옵션을 사용할 수 있지만, 숫자를 “파일 크기가 그만큼 줄어든다”거나 “토큰 요금이 할인된다”는 의미로 해석하면 안 됩니다.
또한 WebP 형식은 손실·무손실 압축을 모두 지원합니다. 그렇다고 GPT Image 2 요청의 압축 설정 하나가 무손실 출력을 보장하는 것은 아닙니다. 먼저 기본 설정으로 저장 과정을 확인하고, 파일 크기를 조정할 때 최종 결과를 다시 검사하는 편이 좋습니다.
생성한 이미지 바이트를 그대로 저장하기
단일 이미지 생성에는 Images API를 사용할 수 있습니다. 아래 예제는 output_format 한 곳을 바꾸면 파일 확장자까지 같이 바뀌도록 작성했습니다. 응답의 b64_json은 이미지 파일 자체가 아니라 Base64 문자열이므로 디코딩해서 바이너리로 저장해야 합니다. Images API 안내
Python 환경에 openai와 Pillow를 설치하고, OPENAI_API_KEY는 환경 변수로 설정하세요. 키를 코드나 공유 로그에 넣지 마세요.
python -m pip install -U openai Pillowimport base64
from pathlib import Path
from openai import OpenAI
client = OpenAI()
output_format = "webp" # PNG가 필요하면 "png"
result = client.images.generate(
model="gpt-image-2",
prompt=(
"앱에서 사용할 작은 우편함 아이콘 하나를 만드세요. "
"피사체만 분리하고 배경은 완전히 투명하게 유지하세요. "
"장면, 단색 배경, 체크무늬와 바닥 그림자는 넣지 마세요. "
"여러 색의 카드 위에 올려도 가장자리가 자연스러워야 합니다."
),
background="transparent",
output_format=output_format,
size="1024x1024",
quality="medium",
)
if not result.data or not result.data[0].b64_json:
raise ValueError("이미지 데이터가 없는 응답입니다")
image_bytes = base64.b64decode(result.data[0].b64_json, validate=True)
if not image_bytes:
raise ValueError("디코딩한 이미지가 비어 있습니다")
output_path = Path(f"mailbox.{output_format}")
output_path.write_bytes(image_bytes)
print(f"저장: {output_path}, {len(image_bytes)} bytes")위 코드는 공식 요청 형식에 따른 구현 예제이며, 유료 API 호출의 성공률이나 생성 품질을 측정한 결과는 아닙니다. 아래 파일 검사 코드는 API 없이 만든 샘플로 동작을 확인할 수 있습니다.
WebP 압축을 조절하려면 client.images.generate(...) 안에 output_compression=80처럼 추가할 수 있습니다. 여기서 80은 설정값의 예시이며 파일 크기, 화질 또는 요금에 대한 보장이 아닙니다. PNG로 바꿀 때는 해당 인수를 제거하세요.
프롬프트에서는 필요한 소재를 구체적으로 설명하고 원하지 않는 배경을 제외합니다. 다만 “투명하게”라는 문장만 넣고 background를 생략하면 같은 요청이 되지 않습니다. auto는 배경 선택을 모델에 맡기므로 투명도가 필수인 소재에는 transparent를 명시하는 것이 적절합니다.

기존 사진의 배경을 없앨 때는 편집 요청을 사용합니다
원본 상품 사진이 있다면 images.edit에 파일을 전달합니다. 생성 예제와 마찬가지로 background와 output_format을 지정하고, 보존할 상품 정보와 제거할 촬영 배경을 나누어 설명하세요.
with open("product.png", "rb") as source:
result = client.images.edit(
model="gpt-image-2",
image=source,
prompt=(
"상품만 남기고 촬영 배경과 바닥 그림자를 제거하세요. "
"상품 형태, 비율, 색상과 라벨 글자를 보존하세요. "
"배경은 완전히 투명하게 유지하고 흰 테두리나 "
"체크무늬를 추가하지 마세요."
),
background="transparent",
output_format=output_format,
)앞 예제의 result를 이 편집 응답으로 바꾸고 동일한 디코딩·저장 부분을 실행하면 됩니다. 라벨 색만 바꾸는 후속 편집에서도 투명 배경을 유지하라는 지시를 다시 넣으세요. OpenAI의 투명 배경 편집 지침
보존 지시는 픽셀 단위 동일성을 보장하지 않습니다. 글자, 로고, 제품 규격처럼 바뀌면 안 되는 요소는 원본과 비교해야 합니다. 반대로 머리카락, 유리, 연기에는 반투명 픽셀이 필요하므로 가장자리를 모두 완전 불투명으로 만드는 방식도 맞지 않습니다.
PNG·WebP에 실제 투명 픽셀이 있는지 검사하기
다음을 inspect_alpha.py로 저장하세요. 확장자와 실제 형식을 비교하고, 완전 투명·반투명·불투명 픽셀 수를 출력합니다. Pillow의 이미지 형식과 채널 처리를 이용하므로 PNG와 WebP 모두 같은 방식으로 검사할 수 있습니다.
from pathlib import Path
import sys
from PIL import Image
path = Path(sys.argv[1])
expected = {".png": "PNG", ".webp": "WEBP"}.get(path.suffix.lower())
with Image.open(path) as source:
source.load()
actual_format = source.format
original_mode = source.mode
rgba = source.convert("RGBA")
histogram = rgba.getchannel("A").histogram()
clear = histogram[0]
soft = sum(histogram[1:255])
solid = histogram[255]
total = rgba.width * rgba.height
print({
"format": actual_format,
"original_mode": original_mode,
"size": rgba.size,
"transparent": clear,
"translucent": soft,
"opaque": solid,
})
if expected is None:
print("형식 확인: PNG 또는 WebP 확장자를 사용하세요")
elif actual_format != expected:
print(f"형식 불일치: 확장자는 {expected}, 내용은 {actual_format}")
if clear == total:
print("빈 투명 이미지: 모든 픽셀의 알파가 0입니다")
elif solid == total:
print("완전 불투명: 투명하거나 반투명한 픽셀이 없습니다")
else:
print("투명도 있음: 가장자리와 피사체 보존 여부를 확인하세요")python inspect_alpha.py mailbox.webp알파는 이 코드에서 0이면 완전 투명, 255이면 완전 불투명입니다. 1~254는 반투명입니다. 원본을 RGBA로 변환하는 이유는 판독 방식을 통일하기 위해서이며, 이 변환이 흰 배경을 제거하지는 않습니다.
결과를 다음처럼 읽으면 됩니다.
- 모든 값이 255: 투명 배경이 없습니다. 흰색이나 체크무늬가 이미지에 직접 그려졌을 가능성도 있습니다.
- 모든 값이 0: 파일은 투명하지만 보이는 피사체가 없습니다. “투명도 성공”으로 처리하면 안 됩니다.
- 0~254인 픽셀이 일부 있음: 투명도는 있습니다. 그러나 작은 구멍 하나만 투명해도 이 결과가 나오므로 배경 제거가 올바르다는 뜻은 아닙니다.
- 모두 중간값: 연기나 유리처럼 완전 투명·불투명 픽셀이 없는 소재일 수 있습니다. 구성에 맞는 결과인지 확인하세요.
미리보기의 흰색·검은색 바탕은 그 자체로 실패의 증거가 아닙니다. 뷰어가 투명 영역 뒤에 바탕색을 표시할 수 있습니다. 체크무늬도 투명도를 보여 주는 뷰어의 표시일 수 있고, 이미지에 직접 그려진 무늬일 수도 있습니다. 화면 색을 추측하기보다 저장한 파일의 알파값으로 먼저 구분하세요.
마지막에는 흰색, 검은색, 실제 사용할 배경색 위에 각각 합성해 보세요. 밝은 배경에서 안 보이던 흰 테두리가 어두운 배경에서 나타날 수 있고, 유리의 반투명 영역이 예상보다 진하게 남을 수도 있습니다. 모든 소재에 공통으로 적용할 “정상 투명 픽셀 비율”은 없습니다.
아래 코드는 같은 파일을 세 가지 바탕색에 올린 확인용 PNG를 만듭니다. alpha_composite는 피사체의 알파값을 반영하므로, 단순히 뷰어 바탕색을 바꾸기 어려울 때 사용할 수 있습니다.
from PIL import Image
with Image.open("mailbox.webp") as source:
subject = source.convert("RGBA")
backgrounds = {
"white": (255, 255, 255, 255),
"black": (0, 0, 0, 255),
"blue": (36, 95, 190, 255),
}
for name, color in backgrounds.items():
canvas = Image.new("RGBA", subject.size, color)
preview = Image.alpha_composite(canvas, subject)
preview.save(f"preview-{name}.png")이 파일들은 배경을 합친 확인용 이미지라서 불투명합니다. 실제 작업에는 원래의 mailbox.webp를 사용하고, 세 미리보기에서 같은 위치에 테두리나 잔여 배경이 보이는지 비교하세요.

PNG 원본을 WebP로 바꾸고 배포할 때
로컬에서 무손실 WebP가 필요하다면 Pillow의 lossless=True를 명시할 수 있습니다. exact=True는 완전 투명 픽셀 안의 RGB 값도 보존하는 옵션입니다. 이는 로컬 인코더 옵션이며 API의 output_compression과 다른 설정입니다. Pillow WebP 저장 옵션
from PIL import Image
with Image.open("mailbox.png") as source:
source.convert("RGBA").save(
"mailbox-web.webp",
format="WEBP",
lossless=True,
exact=True,
)변환한 파일에도 python inspect_alpha.py mailbox-web.webp를 실행하세요. 파일 이름만 .webp로 바꾸는 것은 형식 변환이 아닙니다. 또한 중간에 convert("RGB")를 거치면 알파 채널이 사라집니다. JPEG 전달본을 만드는 과정에서는 투명도를 유지할 수 없으므로, 투명 원본을 따로 보관해야 합니다.
웹에 올렸다면 로컬 원본뿐 아니라 사용자가 실제로 받는 파일을 내려받아 같은 검사를 실행하세요. PNG의 MIME은 image/png, WebP는 image/webp로 맞추고, 응답 헤더와 실제 바이트가 일치하는지 확인합니다. 원본은 투명한데 전달본만 불투명하다면 리사이즈, 포맷 변환, 썸네일 생성 또는 CDN 설정을 좁혀 볼 수 있습니다.
실패한 위치에 따라 다음 확인이 달라집니다
| 증상 | 먼저 확인할 대상 | 다음 조치 |
|---|---|---|
| API가 요청을 거부함 | 오류 본문의 모델·필드 설명, 실제 전송한 요청 | 모델 접근과 지원 필드를 확인하고 PNG 요청의 압축 인수를 제거 |
| HTTP 200인데 이미지 파일을 열 수 없음 | b64_json 존재, 디코딩 결과, 저장 방식 | JSON이나 Base64 문자열 자체를 이미지 확장자로 저장했는지 확인 |
| 확장자는 WebP인데 실제 형식은 PNG·JPEG | 디코딩 직후 파일과 저장 파일 | 요청 형식과 파일명, 중간 변환을 일치시킴 |
| 미리보기에서 흰색·검은색 배경이 보임 | 원본 파일의 알파 통계 | 투명도가 있으면 다른 배경에 합성해 뷰어 표시와 구분 |
| 파일은 정상인데 전부 불투명 | 알파 통계, background 전송 여부 | 배경 조건과 프롬프트를 확인하고 원본 응답도 검사 |
| 모든 알파가 0 | 피사체가 남아 있는지 | 빈 결과로 분류하고 생성·편집 입력 확인 |
| 밝거나 어두운 가장자리가 남음 | 서로 다른 배경에 합성한 결과 | 흰 매트나 색 번짐을 확인하고 마스크·가장자리 보정 검토 |
| 후속 편집에서 배경이 생김 | 마지막 편집의 필드와 지시 | 투명 배경 유지 조건을 다시 명시 |
| 배포본에서만 투명도가 사라짐 | 각 변환 단계의 실제 파일 | 처음 알파를 잃은 처리 단계를 수정 |
OpenAI 호환 중계 서비스를 사용한다면 공식 모델 ID와 동일한 문자열을 받는다는 사실만으로 투명 출력까지 같다고 판단할 수 없습니다. 해당 서비스가 지원하는 필드와 반환 형식을 확인하고, 민감한 키나 원본 사진을 제외한 요청 설정·오류 메시지·파일 형식·알파 통계를 남기면 진단에 도움이 됩니다.
Images API와 Responses API의 이미지 도구는 요청·응답 구조가 다릅니다. 이 글의 result.data[0].b64_json 저장 코드를 Responses 응답에 그대로 적용하지 마세요. 사용할 API부터 정해야 한다면 GPT Image 2 API 사용 방법에서 연결 방식을 확인할 수 있습니다.



