FLUX 3 Image로 포스터 만들기: 바운딩 박스로 배치하고 문구 수정하기
제품 포스터의 구도를 정하고 FLUX 3 바운딩 박스로 변환하는 방법을 알아봅니다. API 요청 준비부터 글자·배치 검수와 부분 수정까지 따라 할 수 있습니다.
FLUX 3 Image로 홍보용 포스터를 만들려면 제품, 제목, 안내 문구에 각각 바운딩 박스를 지정하고, 각 요소의 설명을 프롬프트에 덧붙인 뒤 설계한 종횡비로 생성합니다. 생성된 이미지를 게시용 소재로 사용하기 전에는 글자와 구도를 직접 검수해야 합니다. 박스는 모델이 따를 배치 기준을 제공하지만, 생성 모델을 결과가 항상 일정한 조판 도구로 바꾸지는 않습니다.
이 튜토리얼에서는 4:5 비율의 가상 머그컵 포스터를 만듭니다. 전체 레이아웃, 다운로드할 수 있는 Python 클라이언트, 문구 한 줄을 바꾸는 방법, 게시 전 체크리스트를 제공합니다. 일반 프롬프트로는 보기 좋은 이미지가 나오지만 제목이 제품을 가리거나 행동 유도 문구가 계속 너무 작아지는 상황에 적합한 작업 방식입니다.
검증 범위 — 2026년 10월 7일: 공식 API 문서를 확인하고 실제 문서 화면을 캡처했으며, 요청 구성과 오류 처리 경로를 로컬에서 테스트했습니다. 이 글을 위해 유료 FLUX 생성 요청을 실행하지는 않았습니다. 포스터 기획안은 직접 작성한 예시이며, 아래 이미지를 당사의 생성 결과나 출력 품질을 증명하는 자료로 제시하지 않습니다.
1. 생성기를 열기 전에 기획안 준비하기
튜토리얼 키트를 내려받으세요. flux_poster.py, 함께 제공하는 두 가지 API 실습, 의존성 파일이 포함되어 있습니다. Python 3.10 이상을 사용하고 빈 작업 디렉터리를 준비합니다. 압축을 푼 뒤 스크립트가 있는 디렉터리로 이동하세요.
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
Windows PowerShell에서는 .venv\Scripts\Activate.ps1로 가상 환경을 활성화합니다. 생성에는 BFL API 키가 필요합니다. ChatGPT 구독이나 다른 제공업체의 키를 그대로 쓸 수 있다고 가정하면 안 됩니다. 공식 BFL 대시보드에서 접근 권한을 준비하고, 요청을 실행하기 전에 현재 BFL 요금을 확인하세요. 준비 단계는 로컬에서 진행되지만 생성과 후속 수정은 각각 별도 비용이 발생할 수 있습니다.
이 가상 기획안에는 실제 브랜드명, 가격, 할인 주장을 넣지 않았습니다.
| 결정 항목 | 이번 실습의 값 | 먼저 정하는 이유 |
|---|---|---|
| 캔버스 | 세로형 4:5 | 나중에 비율을 바꾸면 레이아웃의 비례도 달라집니다 |
| 제품 | 손잡이가 오른쪽인 테라코타 머그컵 하나 | 검수할 대상과 방향이 명확해집니다 |
| 제목 | A QUIETER MORNING | 각 글자에 충분한 공간을 줄 수 있는 짧은 문구입니다 |
| 안내 문구 | Autumn collection | 실제로 없는 할인 조건을 만들지 않고 가상 컬렉션을 설명합니다 |
| 행동 유도 문구 | Explore the range | 안내 내용과 사용자의 다음 행동을 구분합니다 |
| 시각적 마감 | 따뜻한 크림색 종이, 짙은 글자 | 대비를 일관되게 검수할 기준이 됩니다 |
실제 캠페인에서는 생성 전에 문구, 날짜, 광고 주장을 승인받아야 합니다. 모델이 할인 조건을 임의로 만들어서는 안 됩니다. 제품의 정확한 외형, 법적 고지, 브랜드 서체를 유지해야 한다면 평소 사용하는 편집 도구에서 해당 소재를 합성할 계획을 세우세요. 텍스트로 일반적인 머그컵을 생성했다고 해서 특정 상품의 외형이 정확히 재현됐다는 뜻은 아닙니다.
2. 레이아웃을 좌표로 바꾸기
FLUX의 박스 형식은 [top, left, bottom, right]입니다. 왼쪽 위를 원점으로 삼고 0부터 1000까지의 정수를 사용합니다. 많은 그래픽 라이브러리의 x좌표 우선 사각형과 순서를 혼동하기 쉽습니다. 가로축과 세로축을 각각 정규화하므로 같은 박스라도 종횡비가 달라지면 실제 픽셀 너비와 높이가 달라집니다. BFL 바운딩 박스 문서.

2026년 10월 7일 캡처한 공식 영어 문서입니다. 필드 형식을 확인하는 자료이며, 이미지 생성이 완료된 결과 화면은 아닙니다. 원문.
이번 예시에서는 다음 레이아웃을 사용합니다.
| 요소 ID | 박스 | 배치할 영역 |
|---|---|---|
| background_1 | [0, 0, 1000, 1000] | 캔버스 전체 |
| headline_1 | [80, 80, 230, 920] | 상단을 넓게 가로지르는 제목 |
| product_1 | [290, 220, 720, 780] | 손잡이 공간을 확보한 중앙 제품 |
| offer_1 | [770, 100, 845, 900] | 제품 아래의 안내 문구 |
| cta_1 | [885, 240, 950, 760] | 하단에 따로 배치한 행동 유도 문구 |
가상의 1000 × 1250 작업 캔버스에서 제품 박스를 픽셀로 환산하면 왼쪽 220, 위 362.5, 오른쪽 780, 아래 900입니다. 이는 좌표 변환 예시이며, API의 1k 설정이 이 해상도를 반환한다는 약속이 아닙니다. 다운로드한 이미지의 실제 크기를 확인하세요.
픽셀 사각형을 변환할 때는 세로 좌표를 이미지 높이로, 가로 좌표를 이미지 너비로 나눈 뒤 1000을 곱해 반올림합니다. top이 bottom보다 작고 left가 right보다 작은지, 네 값 모두 범위 안에 있는지 확인하세요. 키트는 면적이 없는 박스나 중복 요소 ID를 발견하면 요청을 구성하기 전에 거부합니다.
텍스트와 제품 사이에는 여유 공간을 남기세요. 좌표상 간격이 있다고 해서 눈에 보이는 요소가 반드시 분리되는 것은 아닙니다. 글자의 위로 뻗는 획, 그림자, 손잡이가 의도한 영역 밖으로 나올 수 있습니다. 프롬프트의 강조 표현을 계속 늘리기보다 작은 글자에 충분한 공간을 주는 편이 낫습니다.
3. 프롬프트를 만들고 로컬에서 요청 확인하기
이 작업에서는 레이아웃을 prompt 안의 텍스트로 전달합니다. 별도의 bounding_boxes 요청 속성은 사용하지 않습니다. 키트는 <headline_1> 같은 요소 참조가 들어간 전체 설명 뒤에 JSON 배열을 붙입니다. 다음은 이번 예시의 전체 레이아웃 입력입니다.
caption = (
"A vertical promotional poster on a warm cream paper background <background_1>. "
"A single terracotta ceramic mug <product_1> is centered below the large headline <headline_1>. "
"One short offer line <offer_1> and a small call to action <cta_1> sit below the mug. "
"Clean studio lighting, calm editorial design, no brand logo, no additional text."
)
rows = [
{"id": "background_1", "bbox": [0, 0, 1000, 1000],
"desc": "Flat warm cream paper with subtle grain."},
{"id": "headline_1", "bbox": [80, 80, 230, 920],
"desc": 'Large dark serif text reading exactly "A QUIETER MORNING".'},
{"id": "product_1", "bbox": [290, 220, 720, 780],
"desc": "One terracotta ceramic mug, three-quarter view, handle on the right, no lettering."},
{"id": "offer_1", "bbox": [770, 100, 845, 900],
"desc": 'Dark readable text reading exactly "Autumn collection".'},
{"id": "cta_1", "bbox": [885, 240, 950, 760],
"desc": 'Small dark text reading exactly "Explore the range".'},
]
키 없이 준비 명령을 실행합니다.
python flux_poster.py --out prepared-poster
예상 결과는 prepared-poster/request.json 파일과 API 요청을 보내지 않았다는 메시지입니다. 파일을 열어 aspect_ratio: "4:5", resolution: "1k", grounding: false, 다섯 개의 ID, 정확한 세 가지 문구를 확인하세요. 유효한 JSON 파일은 요청을 직렬화할 수 있다는 증거입니다. 모델이 해당 문구를 오탈자 없이 렌더링한다는 증거는 아닙니다.
이 가상 기획안에는 필요한 내용이 이미 있으므로 grounding을 끕니다. 실습을 위한 선택이며, 모든 작업에서 끄라는 일반 권고는 아닙니다. 생성 엔드포인트와 옵션은 FLUX 3 API 개요에 나와 있습니다. 첫 실행은 단순하게 유지하세요. 참조 이미지 추가, 해상도 변경, 레이아웃 재작성을 한꺼번에 진행하지 않는 것이 좋습니다.
4. 생성하고 작업 정보를 보관한 뒤 결과 내려받기
BFL_API_KEY를 로컬 환경 변수로 설정하세요. 스크립트, 스크린샷, 저장소에는 키를 넣지 않습니다. 그다음 새 디렉터리를 지정해 실행합니다.
python flux_poster.py --run --out live-poster
클라이언트는 https://api.bfl.ai/v1/flux-3-image로 요청 본문을 보내고, 반환된 작업 정보를 job.json에 저장한 뒤 반환된 URL을 폴링합니다. Ready 상태에 도달하면 이미지를 내려받아 실제 PNG 파일인 poster.png로 저장하며, 실제 픽셀 크기도 출력합니다. 전체 네트워크 코드가 키트에 있으므로 타임아웃과 오류 처리를 생략 부호 뒤에 숨기지 않았습니다.
스크립트는 폴링 마감 시간을 5분으로 설정합니다. 이미 진행 중인 네트워크 요청은 그 시점 이후에 끝날 수 있습니다. 로컬 타임아웃만으로 원격 작업도 실패했다고 판단할 수는 없습니다. job.json이 있다면 같은 작업의 조회를 재개하세요.
python flux_poster.py --resume --out live-poster
재개 명령은 새 생성 요청을 제출하지 않습니다. 마지막 상태를 갱신하고, 결과가 준비되었으면 해당 작업의 이미지를 갱신합니다. 변경되지 않는 기록이 필요하면 재개 전에 복사본을 보관하세요. 최초 제출 자체가 타임아웃되어 작업 정보가 저장되지 않았다면, 다른 유료 요청을 보내기 전에 제공업체 대시보드에서 확인합니다. 결과 조회 방식은 공식 결과 안내를 참고하세요. 임시 이미지 링크를 블로그의 영구 이미지 주소로 쓰지 말고 결과를 제때 내려받아야 합니다.
5. 레이아웃을 유지하면서 안내 문구 바꾸기
실습에서는 “Autumn collection”을 “Weekend collection”으로 바꿉니다. 다운로드한 이미지는 ref_image_0으로 참조됩니다. 안내 문구의 행은 from: null, src_bbox: null로 설정하고 대상 박스는 유지합니다. 다른 요소의 행은 원본 참조를 유지하고 원본 박스와 대상 박스를 같게 둡니다.
보내기 전에 수정 요청을 확인하세요.
python flux_poster.py --edit live-poster/poster.png --out prepared-edit
준비한 요청이 의도와 일치하면 또 다른 새 디렉터리로 생성합니다.
python flux_poster.py --edit live-poster/poster.png --run --out live-edit
스크립트는 원본 이미지를 요청에 포함합니다. 비공개이거나 이용 권한이 없는 자료가 들어 있다면 생성된 request.json을 공개하지 마세요. 결과물을 공개할 계획이더라도 실제 제품 사진의 사용 권한은 별도로 확인해야 합니다.
유지 행은 어떤 부분을 그대로 두려는지 표현합니다. 나머지 모든 픽셀이 동일하게 유지됐다는 증거는 아닙니다. 원본과 수정본을 같은 크기로 놓고 비교하세요. 바뀐 문구뿐 아니라 머그컵 손잡이, 제목, 그림자, 여백도 확인합니다. 제품이 바뀌었다면 수정본을 채택하지 않거나 일반 편집 도구에서 승인된 텍스트를 합성하세요. 안내 문구가 개선됐다는 이유로 잘못된 제품 이미지를 받아들이면 안 됩니다.
6. 이미지 파일을 넘어 게시용 소재로 검수하기
원래 기획안 옆에 간단한 검수표를 두고 확인합니다.
| 검사 항목 | 통과 조건 | 실패했을 때 |
|---|---|---|
| 텍스트 | 모든 글자, 공백, 대소문자가 승인된 문구와 일치 | 텍스트 영역을 넓히거나 승인된 문구를 줄이거나 별도로 조판 |
| 제품 | 머그컵 하나, 의도한 방향, 추가 손잡이나 임의 브랜드 없음 | 장면을 단순화하고 정확한 정체성이 중요하면 이용 권한이 있는 참조 사용 |
| 시각적 우선순위 | 제목이 먼저 읽히고 제품을 가리지 않으며 행동 유도 문구가 보임 | 경쟁하는 스타일 지시를 늘리기보다 박스를 조정 |
| 수정 | 의도한 줄이 바뀌고 주변의 중요한 내용이 허용 범위 안에서 유지 | 원본과 수정본을 비교하고 승인된 원본을 기준으로 보관 |
| 출력 | 올바른 종횡비, 용도에 맞는 실제 크기, 유효한 이미지 파일 | 파일 확장자만 믿지 말고 다운로드한 파일 검사 |
| 게시 | 근거 없는 혜택, 의도치 않은 로고, 읽기 어려운 작은 글자 없음 | 배포 전에 소재 수정 |
원본 크기와 실제 피드에 노출될 크기에서 모두 확인하세요. 200% 확대했을 때는 올바르게 보이는 제목도 모바일 카드에서는 읽기 어려울 수 있습니다. 프롬프트, 원본 이미지, 모델명, 날짜, 승인된 결과를 함께 보관하면 다음 캠페인 변형도 승인된 버전에서 시작할 수 있습니다.
더 높은 해상도가 있다는 이유만으로 괜찮은 초안을 다시 생성하지 마세요. 먼저 레이아웃과 문구를 확정합니다. 이후 다른 해상도로 요청한다면 새 출력으로 취급하고 검수를 반복하세요. 이 튜토리얼은 생성 간 픽셀 단위로 동일한 업스케일링을 검증하지 않았습니다. 첫 요청만이 아니라 여러 시도와 수정에 필요한 비용까지 고려해야 합니다.
자주 발생하는 문제와 다음 조치
HTTP 401이면 인증을 확인합니다. Python을 실행하는 셸에 BFL 키가 설정되어 있는지 점검하세요. HTTP 400이면 저장된 요청에서 지원되지 않는 옵션 값이나 잘못된 데이터를 확인합니다. 다른 제공업체의 매개변수 이름을 그대로 가져오면 안 됩니다. HTTP 429이면 계정 제한을 확인하고 다음 요청을 늦추세요. 짧은 간격의 무한 재시도는 피합니다.
요소가 엉뚱한 곳에 나타나면 좌표 순서와 종횡비부터 확인하세요. 작은 요소가 사라지면 영역을 넓히고 다른 요소와의 시각적 경쟁을 줄입니다. 안내 문구가 바뀌면서 제품도 변형되었다면 유지 행과 원본 이미지를 비교하세요. 박스는 모델에 방향을 제시하며 래스터 마스크를 강제하지 않습니다. 차단되거나 실패한 작업은 성공으로 처리하지 말고 상태 응답을 보관해 이유를 확인해야 합니다.
포스터가 승인되면 제품 이미지를 가공하거나 영상으로 확장할 수 있습니다. 원본 이미지 준비에는 별도의 제품 사진 배경 작업 과정(영문)을, 움직임 기획에는 제품 사진으로 짧은 영상의 스토리보드 만들기를 참고하세요. 각각 다른 결과물을 만드는 작업입니다. 포스터의 배치가 잘됐다고 해서 영상이나 번역 캠페인까지 검증된 것은 아닙니다.
자주 묻는 질문
- FLUX 3 바운딩 박스 밖의 내용은 모두 잘리나요?
- 아닙니다. 바운딩 박스는 위치와 크기를 안내하며, 엄격한 클리핑 마스크가 아닙니다. 수정 후에는 대상 영역뿐 아니라 이미지의 나머지 부분도 확인해야 합니다.
- API 키 없이 포스터 제작 준비를 실행할 수 있나요?
- 네. 제공 스크립트는 기본적으로 요청을 보내지 않고 request.json만 만듭니다. 이미지를 생성하려면 사용 권한이 있는 BFL 계정과 API 키가 필요하며, 해당 사용 요금이 발생합니다.


