
    Bi!?                       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 ed      Zej)                  dd       ed	z  d
z  dz  Zej)                  dd       dZdZdZdZdZdZdZddZ	 	 	 	 	 	 	 	 	 	 	 	 ddZddZe dk(  r e        yy)uc  M1-1 '정당한 대우' Google 광고 배너 생성기.

Gemini API로 포토리얼 기업 로비 배경을 생성하고,
HTML/CSS + Playwright로 한글 텍스트를 정밀하게 오버레이합니다.

출력:
  - /home/jay/workspace/output/google-ads/banners/m1/m1-1-1200x628.png
  - /home/jay/workspace/output/google-ads/banners/m1/m1-1-1080x1080.png
    )annotationsN)Path)sync_playwrightz0/home/jay/workspace/output/google-ads/banners/m1Tparentsexist_okoutputz	v4-hybridz	m1-1-fairz0https://generativelanguage.googleapis.com/v1betaz3https://www.googleapis.com/auth/generative-languagez)gemini-2.0-flash-preview-image-generationzgemini-2.5-flash-imageuj  Photographic scene of a modern corporate headquarters lobby in Seoul. Wide shot, shot from low angle (waist height), looking slightly upward. Floor-to-ceiling glass walls revealing city skyline in the background. Clean white marble floor with subtle dark veining. Warm indirect lighting from recessed ceiling fixtures casting a soft glow. Early morning light filtering through the glass, golden hour quality. One male professional in his mid-30s, rear view only — no face visible — wearing a well-fitted dark navy suit, walking confidently toward the elevator bank in the middle distance. The person occupies roughly the right third of the frame, leaving the left two-thirds open for text overlay. Shallow depth of field, the background city slightly blurred. Shot on full-frame DSLR quality, f/2.8, natural cinematic color grading. Corporate, trustworthy, aspirational.uO  <!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 right;
  }}

  /* 좌측 딥 네이비 그라데이션 오버레이 (0~720px) */
  .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: 40px;
    font-weight: 700;
    height: 48px;
    line-height: 48px;
    padding: 8px 20px;
    border-radius: 4px;
    letter-spacing: -0.03em;
    white-space: nowrap;
    box-sizing: content-box;
  }}

  /* 메인 헤드라인 */
  .headline {{
    font-size: 58px;
    font-weight: 700;
    color: #F0F4F8;
    line-height: 1.2;
    letter-spacing: -0.02em;
    margin-top: 28px;
    word-break: keep-all;
  }}

  /* 서브카피 */
  .subcopy {{
    font-size: 44px;
    font-weight: 500;
    color: #F0F4F8;
    line-height: 1.4;
    letter-spacing: 0.01em;
    margin-top: 20px;
    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: 44px;
    font-weight: 700;
    padding: 14px 36px;
    border-radius: 6px;
    letter-spacing: 0.02em;
    min-width: 220px;
    text-align: center;
    line-height: 1.2;
    box-shadow: 0 4px 16px rgba(197, 165, 114, 0.35);
  }}
</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">투명한 수수료 구조 | 정착률 99%</div>
  </div>
  <div class="cta-btn">조건 확인하기 →</div>
</div>
</body>
</html>uX  <!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;
  }}

  /* 전체 딥 네이비 반투명 오버레이 */
  .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: 40px;
    font-weight: 700;
    height: 52px;
    line-height: 52px;
    padding: 10px 24px;
    border-radius: 4px;
    letter-spacing: -0.03em;
    white-space: nowrap;
    box-sizing: content-box;
  }}

  /* 메인 헤드라인 */
  .headline {{
    font-size: 64px;
    font-weight: 700;
    color: #F0F4F8;
    line-height: 1.2;
    letter-spacing: -0.02em;
    text-align: center;
    margin-top: 36px;
    word-break: keep-all;
  }}

  /* 서브카피 */
  .subcopy {{
    font-size: 44px;
    font-weight: 500;
    color: #F0F4F8;
    line-height: 1.4;
    text-align: center;
    margin-top: 24px;
    word-break: keep-all;
    white-space: nowrap;
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
  }}

  /* 서브카피2 */
  .subcopy2 {{
    font-size: 44px;
    font-weight: 500;
    color: #F0F4F8;
    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: 48px;
    font-weight: 700;
    padding: 18px 56px;
    width: 360px;
    height: 68px;
    border-radius: 6px;
    letter-spacing: 0.02em;
    text-align: center;
    line-height: 68px;
    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">투명한 수수료 구조 | 정착률 99%</div>
    <div class="subcopy2">경력직 정착금 최대 50%</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로 배경 이미지를 생성하고 저장합니다.uC   [배경] 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     G/home/jay/workspace/tools/ai-image-gen/_backup/gen_m1_1_fair_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_imagerK   g  s   	OPXzYZ
[\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   )rO   yrR   rS   )pathtypeclipu   [캡처] 저장 완료: N)
missing_ok)resolveformatTMP_DIR
write_textr(   r   chromiumlaunchnew_pagegotowait_for_timeoutparentmkdir
screenshotstrcloseunlink)html_contentbg_pathr>   rR   rS   rM   html_filledtmp_htmlr   browserpages              r   capture_html_to_pngrr     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<============================================================u3   M1-1 '정당한 대우' Google 배너 생성 시작u!   
[인증] SA 토큰 획득 중...u'   [인증] 토큰 획득 성공 (길이: z chars)u   [인증] 실패:    u(   
[배경] 배경 이미지 확인 중...bg_m1_1_fairzbg_m1_1_fair.*r   u%   [배경] 기존 이미지 재사용: u   [배경] 생성 실패: u,   
[배너 1] 1200x628 가로형 생성 중...zm1-1-1200x628.pngi  it  )rl   rm   r>   rR   rS   i   u   [배너 1] 완료: r&   z.0fz KB)u   [배너 1] 실패: u0   
[배너 2] 1080x1080 정사각형 생성 중...zm1-1-1080x1080.pngi8  u   [배너 2] 완료: u   [배너 2] 실패: z=
============================================================u   생성 완료u     배너 1: u     배너 2: )r(   gcloud_authget_access_tokenr<   	Exception
SystemExitr_   listglobr;   rK   
OUTPUT_DIRrr   HTML_1200x628statst_size	traceback	print_excHTML_1080x1080)	r=   ebg_tmp_pathexistingrm   output_1200size_kbr   output_1080s	            r   mainr     sl   	(O	
?@	(O 

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

56N*KGLL!123H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__)r=   ri   r>   r   returnr   )rl   ri   rm   r   r>   r   rR   intrS   r   r   None)r   r   )!__doc__
__future__r   r7   r   sysr*   pathlibr   r-   playwright.sync_apir   __file__rf   TOOL_DIRrY   insertri   rv   r|   rg   r_   r+   GEMINI_SCOPEr)   r0   r,   r}   r   rK   rr   r   __name__r       r   <module>r      s$   #   
    / >   3x= ! DE
 
    -
X

+k
9 dT * ED6, 
T 
"QfQl0j%%% % 	%
 % 
%HBJ zF r   