
    i^A                    <   d Z ddlmZ ddlZddlZddlZddlZddlmZ ddl	Z	ddl
mZ  ee      j                  Zej                  j!                  d ee             ddlZddlmZmZmZ eZdZdZd	ZeZdZd
ZdZdZdZ edz  Z!e!jE                  dd       edz  dz  dz  Z#e#jE                  dd       dZ$dZ%dZ&dZ'dZ(de de de de de de  de d e d!Z)d"e d#e d$e de d%e de  d&e d'e d(e d)Z*d.d*Z+	 	 	 	 	 	 	 	 	 	 	 	 d/d+Z,d0d,Z-e.d-k(  r e-        yy)1u  인카다이렉트 M1-3 '인카다이렉트 × 영업지원' Google 광고 배너 생성기.

Gemini API로 밝은 코워킹 스페이스 배경을 생성하고,
HTML/CSS + Playwright로 한글 텍스트를 정밀하게 오버레이합니다.

출력:
  - /home/jay/workspace/output/google-ads/banners/m1/m1-3-1200x628.png
  - /home/jay/workspace/output/google-ads/banners/m1/m1-3-1080x1080.png
    )annotationsN)Path)sync_playwright)
CTA_MIN_PXSUBHEAD_MIN_PXWORKSPACE_ROOT,   0   :   4   D   g333333?gffffff?zoutput/google-ads/banners/m1Tparentsexist_okoutputz	v4-hybridzm1-3-supportz0https://generativelanguage.googleapis.com/v1betaz3https://www.googleapis.com/auth/generative-languagez)gemini-2.0-flash-preview-image-generationzgemini-2.5-flash-imageu  Photographic scene of a bright, contemporary co-working space in Seoul. Shot from slightly above eye level, front-facing angle toward a single workstation. Two large monitors on a clean white standing desk with adjustable height. A person visible from the left side only — showing the arm and shoulder in a casual business-casual shirt (light blue or white), hands on keyboard. Face completely off-frame. A ceramic coffee mug on the right side of the desk, and a small succulent plant at the corner. Warm natural sunlight streaming from a large window on the left side of the frame. The background shows other co-workers blurred in bokeh. Bright, welcoming, approachable atmosphere. Shot on mirrorless camera quality, wide aperture. The overall feel is energetic but calm.u  <!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1200">
<style>
  @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;500;700;900&display=swap');

  * { margin: 0; padding: 0; box-sizing: border-box; }

  body {
    width: 1200px;
    height: 628px;
    overflow: hidden;
    font-family: 'Pretendard', 'Noto Sans KR', 'Apple SD Gothic Neo', sans-serif;
  }

  .banner {
    position: relative;
    width: 1200px;
    height: 628px;
    overflow: hidden;
    background: #1B365D;
  }

  /* 배경 이미지 - 전체 */
  .bg-image {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    background-image: url('{bg_url}');
    background-size: cover;
    background-position: center;
  }

  /* 좌측 딥 네이비 그라데이션 오버레이 */
  .left-overlay {
    position: absolute;
    top: 0; left: 0;
    width: 720px;
    height: 100%;
    background: linear-gradient(
      to right,
      rgba(27, 54, 93, 0.88) 0%,
      rgba(27, 54, 93, 0.82) 70%,
      rgba(27, 54, 93, 0.40) 90%,
      rgba(27, 54, 93, 0.00) 100%
    );
  }

  /* 골드 세로 액센트바 */
  .accent-bar {
    position: absolute;
    top: 80px; left: 0;
    width: 4px; height: 460px;
    background: linear-gradient(to bottom, #C5A572, #D4B87A);
    border-radius: 2px;
  }

  /* 텍스트 콘텐츠 영역 */
  .text-area {
    position: absolute;
    top: 0; left: 0;
    width: 620px;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 52px 60px;
    gap: 0;
  }

  /* 뱃지 */
  .badge {
    display: inline-block;
    background: #C5A572;
    color: #1B365D;
    font-size: z=px;
    font-weight: 700;
    height: 48px;
    line-height: u   px;
    padding: 8px 20px;
    border-radius: 4px;
    letter-spacing: -0.03em;
    white-space: nowrap;
    box-sizing: content-box;
    margin-bottom: 20px;
  }

  /* 메인 헤드라인 */
  .headline {
    font-size: z?px;
    font-weight: 700;
    color: #F0F4F8;
    line-height: u   ;
    letter-spacing: -0.01em;
    margin-bottom: 20px;
    word-break: keep-all;
  }

  /* 지원 항목 */
  .subcopy {
    font-size: z?px;
    font-weight: 500;
    color: #F0F4F8;
    line-height: uw  ;
    letter-spacing: -0.03em;
    margin-bottom: 36px;
    word-break: keep-all;
    white-space: nowrap;
    text-shadow: 0 1px 3px rgba(0,0,0,0.4);
  }

  /* CTA 버튼 */
  .cta-btn {
    position: absolute;
    bottom: 52px;
    left: 60px;
    display: inline-block;
    background: linear-gradient(135deg, #C5A572 0%, #D4B87A 100%);
    color: #1A0E00;
    font-size: zpx;
    font-weight: 700;
    padding: 14px 36px;
    border-radius: 6px;
    letter-spacing: 0.02em;
    min-width: 220px;
    text-align: center;
    line-height: u  ;
    box-shadow: 0 4px 16px rgba(197, 165, 114, 0.35);
    font-family: 'Pretendard', 'Noto Sans KR', 'Apple SD Gothic Neo', sans-serif;
  }
</style>
</head>
<body>
<div class="banner">
  <div class="bg-image"></div>
  <div class="left-overlay"></div>
  <div class="accent-bar"></div>
  <div class="text-area">
    <div class="badge">인카금융서비스 | 영업지원</div>
    <div class="headline"><span style="color:#C5A572">무자본창업</span>,<br>인카가 도와드립니다</div>
    <div class="subcopy">DB 자동화 | AI 무상 세팅 | <span style="color:#F0F4F8; font-weight:700">정착금 1,000만원</span></div>
  </div>
  <div class="cta-btn">무료 상담 신청 →</div>
</div>
</body>
</html>uM  <!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1080">
<style>
  @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;500;700;900&display=swap');

  * { margin: 0; padding: 0; box-sizing: border-box; }

  body {
    width: 1080px;
    height: 1080px;
    overflow: hidden;
    font-family: 'Pretendard', 'Noto Sans KR', 'Apple SD Gothic Neo', sans-serif;
  }

  .banner {
    position: relative;
    width: 1080px;
    height: 1080px;
    overflow: hidden;
    background: #1B365D;
  }

  /* 배경 이미지 전체 */
  .bg-image {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    background-image: url('{bg_url}');
    background-size: cover;
    background-position: center center;
  }

  /* 전체 딥 네이비 반투명 오버레이 */
  .full-overlay {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    background: rgba(27, 54, 93, 0.60);
  }

  /* 전체 텍스트 레이아웃 */
  .content {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 80px 72px;
  }

  /* 뱃지 */
  .badge {
    display: inline-block;
    background: #C5A572;
    color: #1B365D;
    font-size: z=px;
    font-weight: 700;
    height: 52px;
    line-height: u   px;
    padding: 10px 24px;
    border-radius: 4px;
    letter-spacing: -0.03em;
    white-space: nowrap;
    box-sizing: content-box;
  }

  /* 메인 헤드라인 */
  .headline {
    font-size: u   ;
    letter-spacing: -0.02em;
    text-align: center;
    margin-top: 36px;
    word-break: keep-all;
  }

  /* 서브카피 */
  .subcopy {
    font-size: u   ;
    text-align: center;
    margin-top: 24px;
    word-break: keep-all;
    white-space: nowrap;
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
  }

  /* 강조 서브카피 */
  .subcopy-highlight {
    font-size: u  px;
    font-weight: 700;
    color: #C5A572;
    text-align: center;
    margin-top: 24px;
    word-break: keep-all;
    white-space: nowrap;
    text-shadow: 0 1px 3px rgba(0,0,0,0.4);
  }

  /* CTA 버튼 */
  .cta-btn {
    position: absolute;
    bottom: 100px;
    left: 50%;
    transform: translateX(-50%);
    display: inline-block;
    background: linear-gradient(135deg, #C5A572 0%, #D4B87A 100%);
    color: #1A0E00;
    font-size: zpx;
    font-weight: 700;
    padding: 18px 56px;
    width: 400px;
    height: 68px;
    border-radius: 6px;
    letter-spacing: 0.02em;
    text-align: center;
    line-height: u  px;
    white-space: nowrap;
    box-shadow: 0 4px 16px rgba(197, 165, 114, 0.35);
    box-sizing: content-box;
  }
</style>
</head>
<body>
<div class="banner">
  <div class="bg-image"></div>
  <div class="full-overlay"></div>
  <div class="content">
    <div class="badge">인카금융서비스 | 영업지원</div>
    <div class="headline"><span style="color:#C5A572">무자본창업</span>,<br>인카가 도와드립니다</div>
    <div class="subcopy">DB 자동화 | AI 무상 세팅</div>
    <div class="subcopy-highlight">신입 정착금 최대 1,000만원</div>
  </div>
  <div class="cta-btn">무료 상담 신청 →</div>
</div>
</body>
</html>c           	        t        dt         d       t        j                         }t         dt         d}d|  dd}dd	t        igigd
ddgid}t        j                  |||d      }|j                  dv rOt        dt         d|j                   dt                t         dt         d}t        j                  |||d      }|j                  s8t        d|j                   d|j                  dd         |j                          |j                         }|j                  dg       }	|	s$t        dt        j                  |      dd        |	d   j                  di       j                  dg       }
t!        d |
D        d      }|5|
D cg c]  }d	|v s|j                  d	d       }}t        d|dd        |d    j                  d!d"      }t#        j$                  |d    d#         }d$|v rd%nd&}|j'                  |      }|j)                  |       t        j                         |z
  }t        d'|j*                   d(t-        |      d)d*|d+d,       |S c c}w )-u?   Gemini API로 배경 이미지를 생성하고 저장합니다.uL   [배경] Gemini API로 코워킹 스페이스 배경 생성 중... (모델: )z/models/z:generateContentzBearer zapplication/json)AuthorizationzContent-TypepartstextresponseModalitiesIMAGETEXT)contentsgenerationConfigi,  )headersjsontimeout)  i  i  u   [배경] 모델 u    실패 (HTTP z). Fallback: u   [배경] API 오류: z - Nr   
candidatesu   응답에 candidates 없음: r   contentc              3  *   K   | ]  }d |v s|  yw)
inlineDataN ).0ps     \/home/jay/workspace/.worktrees/task-2116-dev1/tools/ai-image-gen/gen_m1_3_support_banners.py	<genexpr>z$generate_bg_image.<locals>.<genexpr>  s     =Q<1+<q=s   	 u'   이미지 데이터 없음. 텍스트:    r#   mimeTypez
image/jpegdatajpegz.jpgz.pngu   [배경] 완료:  (,z bytes, z.1fu   초))printMODEL_IDtimeGEMINI_API_BASE	BG_PROMPTrequestspoststatus_codeFALLBACK_MODEL_IDokr   raise_for_statusr   getRuntimeErrordumpsnextbase64	b64decodewith_suffixwrite_bytesnamelen)tokenoutput_pathstarturlr   payloadresponseurl2r,   r    r   
image_partr&   
text_parts	mime_typeimage_bytesext
final_pathelapseds                      r'   generate_bg_imagerS   v  s   	XYaXbbc
deIIKEXhZ/?
@C"5'**G
  34561GV3DEG
 }}S'MH . 
.9M9M8Nm\m[nop!"(+<*==MN==wWcR;;%h&:&:%;3x}}Tc?R>STU!!#==?D,+J:4::d;KDS;Q:RSTTqMi,00"=E=%=tDJ16FA&A+aeeFB'F
FDZPRQR^DTUVV<(,,ZFI"":l#;F#CDKi'&VC((-J;'iikE!G	joo.b[1A!0DHWUXMY]
^_ Gs   	I!I!c           
        d|j                          }| j                  |      }t        d| d| dz  }|j                  |d       t	        d| d| d	       t               5 }|j                  j                  d
dg      }		 |	j                  ||d      }
|
j                  d|j                          d       |
j                  d       |j                  j                  dd       |
j                  t        |      ddd||d       t	        d|        |	j                          	 ddd       |j!                  d       y# |	j                          w xY w# 1 sw Y   1xY w)uY   HTML 템플릿에 배경 이미지 URL을 삽입하고 Playwright로 PNG 캡처합니다.zfile://)bg_urltmp_xz.htmlzutf-8)encodingu   [캡처] Playwright로 u    캡처 중...z--no-sandboxz--disable-gpu)args)widthheight)viewportnetworkidle)
wait_untili	  Tr   pngr   )rW   yrZ   r[   )pathtypeclipu   [캡처] 저장 완료: N)
missing_ok)resolveformatTMP_DIR
write_textr0   r   chromiumlaunchnew_pagegotowait_for_timeoutparentmkdir
screenshotstrcloseunlink)html_contentbg_pathrF   rZ   r[   rU   html_filledtmp_htmlr&   browserpages              r'   capture_html_to_pngrz     sm    w()*F%%V%4K 4waxu55Hg6	#E7!F8>
BC		 a**##./)J#K	##u-O#PDII 0 0 234IO!!$'$$TD$AOO[!1Q&EO  ,[M:;MMO OOtO$ MMO s%   %EBEEEEE&c                    t        d       t        d       t        d       t        d       	 t        j                         } t        dt        |        d       t        d       t        d	z  }t        t        j                  d
            }|r|d   }t        d|j                          n	 t        | |      }t        d       t        dz  }	 t        t        ||dd       |j                         j                  dz  }t        d| d|dd       t        d       t        dz  }	 t        t$        ||dd       |j                         j                  dz  }t        d| d|dd       t        d       t        d       t        d |        t        d!|        t        d       y # t        $ r}t        d|        t        d      |d }~ww xY w# t        $ r}t        d|        t        d      |d }~ww xY w# t        $ r-}t        d|        dd l}|j#                          Y d }~d }~ww xY w# t        $ r,}t        d|        dd l}|j#                          Y d }~d }~ww xY w)"Nz<============================================================uX   인카다이렉트 M1-3 '인카다이렉트 × 영업지원' Google 배너 생성 시작u!   
[인증] SA 토큰 획득 중...u'   [인증] 토큰 획득 성공 (길이: z chars)u   [인증] 실패:    u(   
[배경] 배경 이미지 확인 중...bg_m1_3_supportzbg_m1_3_support.*r   u%   [배경] 기존 이미지 재사용: u   [배경] 생성 실패: u,   
[배너 1] 1200x628 가로형 생성 중...zm1-3-1200x628.pngi  it  )rt   ru   rF   rZ   r[   i   u   [배너 1] 완료: r.   z.0fz KB)u   [배너 1] 실패: u0   
[배너 2] 1080x1080 정사각형 생성 중...zm1-3-1080x1080.pngi8  u   [배너 2] 완료: u   [배너 2] 실패: z=
============================================================u   생성 완료u     배너 1: u     배너 2: )r0   gcloud_authget_access_tokenrD   	Exception
SystemExitrg   listglobrC   rS   
OUTPUT_DIRrz   HTML_1200x628statst_size	traceback	print_excHTML_1080x1080)	rE   ebg_tmp_pathexistingru   output_1200size_kbr   output_1080s	            r'   mainr     sm   	(O	
de	(O 

./#,,.7E
|7KL 

56--KGLL!456H1+5gll^DE	''{;G 

9:22K0&#	
 ""$,,t3#K=73-tDE 

=>33K0'#	
 ""$,,t3#K=73-tDE
 
/	/	L
&'	L
&'	(Oq  #!!%&m"#  	',QC01Q-Q&	'"  0#A3'()--//0"  0#A3'()--//0sa   ,F) -G AG? 'AH8 )	G2GG	G<G77G<?	H5"H00H58	I-"I((I-__main__)rE   rq   rF   r   returnr   )rt   rq   ru   r   rF   r   rZ   intr[   r   r   None)r   r   )/__doc__
__future__r   r?   r   sysr2   pathlibr   r5   playwright.sync_apir   __file__rn   TOOL_DIRra   insertrq   r~   
gen_configr   r   r   _CTA_PX
_SIZE_44PX
_SIZE_48PX
_SIZE_58PX_SUBHEAD_PX_LH_48PX_LH_52PX_LH_68PX_LH_1_2_LH_1_4r   ro   rg   r3   GEMINI_SCOPEr1   r8   r4   r   r   rS   rz   r   __name__r$       r'   <module>r      s;   #   
    / >   3x= !  A A 




 <<
 
    -
X

+n
< dT * ED6, 

M 
 MZ y    |    |     |   ASj<x y   
 }   	 y   
 | & |   {Ql0j%%% % 	%
 % 
%HBJ zF r   