
    i@                       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j                  j                  d e ee      j                                ddlZddlmZmZmZmZmZmZ eZdZdZeZd	ZeZd
ZdZ dZ!dZ"eZ#edz  Z$dZ%dZ&dZ'dZ(ddddddddddZ)d"dZ*d"dZ+d"dZ,d#dZ-d$dZ.d%d Z/e0d!k(  r e/        yy)&u   컨셉 21(코카콜라), 22(갤럭시), 23(나이키) 하이브리드 이미지 생성기.

1단계: Gemini API로 배경 이미지 생성
2단계: Playwright로 HTML/CSS 텍스트 오버레이 합성 → PNG 저장
    )annotationsN)Path)sync_playwright)CORE_METRIC_MIN_PX
CTA_MIN_PXFONT_DIRHEAD_SUB_RATIOSUBHEAD_MIN_PXWORKSPACE_ROOT*   ,   X   p   g?gffffff?g333333?zoutput/meta-ads/concept-catalogz0https://generativelanguage.googleapis.com/v1betaz3https://www.googleapis.com/auth/generative-languagezgemini-3.1-flash-image-previewzgemini-3-pro-image-previewz21-cocacola-stylea  Warm cream white background with soft red wave curves at the top, warm and inviting atmosphere, soft golden hour lighting feel, no text, no people, abstract warm shapes, cream white base #FFFDF9, red accent curves #F40009, golden yellow #FFCC00, 1080x1080 square)folder	bg_promptz22-galaxy-stylezDeep space galaxy gradient background, dark navy #0A0E2E to purple #7B2FBE to electric blue, floating luminous particles and light streaks, premium tech aesthetic, cinematic quality, no text, abstract futuristic atmosphere, 1080x1080 squarez23-nike-stylezPure solid black background #0D0D0D, subtle very faint diagonal light streak from upper right corner, minimal, dramatic, no text, no objects, cinematic dark atmosphere, 1080x1080 square212223c                b    dt          d|  dt         dt         dt         dt         dt
         dS )	u,   #21 코카콜라 스타일 HTML 오버레이zS<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
  @import url('file://a  /PretendardVariable.ttf');
  * { margin: 0; padding: 0; box-sizing: border-box; }
  body { width: 1080px; height: 1080px; overflow: hidden; font-family: 'Pretendard', 'Noto Sans KR', sans-serif; }
  .canvas {
    width: 1080px; height: 1080px;
    background-image: url('file://a  ');
    background-size: cover; background-position: center;
    position: relative;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
  }
  .overlay {
    position: absolute; inset: 0;
    background: rgba(255, 253, 249, 0.15);
  }
  .content {
    position: relative; z-index: 10;
    text-align: center;
    padding: 0 80px;
    display: flex; flex-direction: column;
    align-items: center; gap: 32px;
  }
  .headline {
    font-size: z?px;
    font-weight: 800;
    color: #1A0A00;
    line-height: zn;
    letter-spacing: -2px;
    text-shadow: 0 2px 8px rgba(255,253,249,0.8);
  }
  .subtext {
    font-size: z?px;
    font-weight: 400;
    color: #1A0A00;
    line-height: z;
    text-shadow: 0 1px 4px rgba(255,253,249,0.8);
  }
  .cta {
    display: inline-block;
    background: #F40009;
    color: #FFFFFF;
    font-size: u  px;
    font-weight: 700;
    padding: 22px 60px;
    border-radius: 60px;
    letter-spacing: 0;
    margin-top: 8px;
    box-shadow: 0 8px 32px rgba(244,0,9,0.4);
  }
  .top-banner {
    position: absolute; top: 0; left: 0; right: 0;
    height: 140px;
    background: #F40009;
    clip-path: ellipse(60% 100% at 50% 0%);
  }
  .golden-dot {
    position: absolute; bottom: 60px; left: 50%; transform: translateX(-50%);
    width: 80px; height: 8px; background: #FFCC00; border-radius: 4px;
  }
</style>
</head>
<body>
<div class="canvas">
  <div class="overlay"></div>
  <div class="top-banner"></div>
  <div class="content">
    <div class="headline">열심히는 하는데,<br>월급은 제자리걸음?</div>
    <div class="subtext">당신의 이야기, 우리가 알고 있습니다</div>
    <div class="cta">지금 확인하기 →</div>
  </div>
  <div class="golden-dot"></div>
</div>
</body>
</html>)r   
_METRIC_PX_LH_1_15_SUBHEAD_PX	_LH_RATIO
_SIZE_44PXbg_paths    Y/home/jay/workspace/.worktrees/task-2116-dev1/tools/ai-image-gen/gen_concepts_21_22_23.pymake_html_21r   Q   sh    
  j !#
 $+) ,$ |   
 }    |  ]N N    c                T    d|  dt          dt         dt         dt         dt         dS )u)   #22 갤럭시 스타일 HTML 오버레이8  <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
  * { margin: 0; padding: 0; box-sizing: border-box; }
  body { width: 1080px; height: 1080px; overflow: hidden; font-family: 'Pretendard', 'Noto Sans KR', sans-serif; }
  .canvas {
    width: 1080px; height: 1080px;
    background-image: url('file://a  ');
    background-size: cover; background-position: center;
    position: relative;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
  }
  .overlay {
    position: absolute; inset: 0;
    background: linear-gradient(180deg, rgba(10,14,46,0.2) 0%, rgba(10,14,46,0.6) 100%);
  }
  .content {
    position: relative; z-index: 10;
    text-align: center;
    padding: 0 80px;
    display: flex; flex-direction: column;
    align-items: center; gap: 36px;
  }
  .headline {
    font-size: ?px;
    font-weight: 900;
    color: #FFFFFF;
    line-height: z;
    letter-spacing: -2px;
    text-shadow: 0 0 60px rgba(91,191,255,0.5), 0 4px 16px rgba(0,0,0,0.6);
  }
  .subtext {
    font-size: z?px;
    font-weight: 300;
    color: #5BBFFF;
    line-height: z;
    text-shadow: 0 0 30px rgba(91,191,255,0.6);
  }
  .cta {
    display: inline-block;
    background: rgba(91, 191, 255, 0.12);
    color: #FFFFFF;
    font-size: u  px;
    font-weight: 500;
    padding: 20px 56px;
    border: 2px solid rgba(91, 191, 255, 0.7);
    border-radius: 60px;
    letter-spacing: 1px;
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    box-shadow: 0 0 32px rgba(91,191,255,0.25), inset 0 1px 0 rgba(255,255,255,0.2);
  }
  .accent-line {
    position: absolute; bottom: 80px; left: 50%; transform: translateX(-50%);
    width: 120px; height: 3px;
    background: linear-gradient(90deg, transparent, #5BBFFF, transparent);
  }
</style>
</head>
<body>
<div class="canvas">
  <div class="overlay"></div>
  <div class="content">
    <div class="headline">열심히는 하는데,<br>월급은 제자리걸음?</div>
    <div class="subtext">기술이 당신의 커리어를 업그레이드합니다</div>
    <div class="cta">T.O.P 확인하기</div>
  </div>
  <div class="accent-line"></div>
</div>
</body>
</html>)
_SIZE_88PX_LH_1_2r   r   
_SIZE_42PXr   s    r   make_html_22r'      s\    	# $+) ,$ |   
 }    | [I Ir    c                T    d|  dt          dt         dt         dt         dt         dS )u)   #23 나이키 스타일 HTML 오버레이r"   a  ');
    background-size: cover; background-position: center;
    position: relative;
  }
  .overlay {
    position: absolute; inset: 0;
    background: rgba(13, 13, 13, 0.25);
  }
  .sub-pre {
    position: absolute;
    top: 240px; left: 80px;
    font-size: zNpx;
    font-weight: 400;
    color: rgba(255,255,255,0.85);
    line-height: zq;
    letter-spacing: -1px;
  }
  .headline {
    position: absolute;
    top: 330px; left: 80px;
    font-size: r#   z;
    letter-spacing: -4px;
    text-transform: none;
  }
  .cta {
    position: absolute;
    bottom: 100px; right: 80px;
    font-size: u  px;
    font-weight: 700;
    color: #FF4500;
    letter-spacing: 0;
  }
  .cta-underline {
    position: absolute;
    bottom: 88px; right: 80px;
    width: 220px; height: 3px;
    background: #FF4500;
    opacity: 0.7;
  }
</style>
</head>
<body>
<div class="canvas">
  <div class="overlay"></div>
  <div class="sub-pre">열심히는 하는데,</div>
  <div class="headline">월급은<br>제자리걸음?</div>
  <div class="cta">지금 바꿔 →</div>
  <div class="cta-underline"></div>
</div>
</body>
</html>)r   r%   _SIZE_112PX_LH_1_1_CTA_PXr   s    r   make_html_23r,      sZ    	# $+) , }    }    y O> >r    c                   t         t        fD ]  }t         d| d}d|  dd}dd|igigdd	d
gid}t        d| d| d       	 t	        j
                  |||d      }|j                  dv rt        d| d|j                   d       ~|j                          |j                         }	|	j                  di g      d   j                  di       j                  dg       }
t        d |
D        d      }|4t        d| d|
D cg c]  }|j                  dd      dd  c}        |d   j                  dd      }d|v rd nd!}|j                  |      }|j                  t        j                  |d   d"                t        d| d#| d$|j                         j                   d%d&       ||k7  rddl}|j%                  ||        y' y)c c}w # t&        $ r}t        d| d(|        Y d}~d}~ww xY w)*uL   Gemini API로 배경 이미지를 생성하여 저장. 성공 여부 반환.z/models/z:generateContentzBearer zapplication/json)AuthorizationzContent-TypepartstextresponseModalitiesIMAGETEXT)contentsgenerationConfig  [u'   ] Gemini 배경 생성 중... (모델: )i,  )headersjsontimeout)i  i  ] u    — 다음 모델 시도
candidatesr   contentc              3  *   K   | ]  }d |v s|  yw)
inlineDataN ).0ps     r   	<genexpr>zgenerate_bg.<locals>.<genexpr>K  s     C11BQCs   	Nu   ] 이미지 파트 없음:  P   r?   mimeTypez
image/jpegjpeg.jpg.pngdatau   ] 배경 저장:  (, bytes)Tu
   ] 오류: F)MODEL_IDFALLBACK_MODEL_IDGEMINI_API_BASEprintrequestspoststatus_coderaise_for_statusr9   getnextwith_suffixwrite_bytesbase64	b64decodestatst_sizeshutilcopy2	Exception)tokenpromptoutput_pathlabelmodelurlr8   payloadresprJ   r/   img_partrB   mimeextactual_pathr^   es                     r   generate_bgrn   9  s>   -. . !%0@A&-eW$5GYZ!VV$4#567!57H I
 	E7A%JK	.==gGSQD:-E7"T%5%5$66OPQ!!#99;DHH\B40377	2FJJ7TVWECCTJHE7"=^c>dYZquuVB?OPSQS?T>d=efgL)--j,GD"dN&C%11#6K##F$4$4Xl5KF5S$TUCw/}B{?O?O?Q?Y?YZ[>\\cdek)[+6;.@  ?e  	.Cwj,--	.s9   AGA8GG	G*B!GG	G9G44G9c           
        |j                   dz  }|j                  | d       t               5 }|j                  j	                  ddg      }	 |j                  ddd	      }|j                  d
|j                          d       |j                  d       |j                   j                  dd       |j                  t        |      d       t        d| d| d|j                         j                  dd       |j                          	 ddd       |j!                  d       y# |j                          w xY w# 1 sw Y   1xY w)uC   HTML 문자열을 임시 파일로 저장 후 Playwright로 캡처.z_overlay_tmp.htmlzutf-8)encodingz--disable-web-securityz--allow-file-access-from-files)argsi8  )widthheight)viewportzfile://networkidle)
wait_untili  Tparentsexist_okpng)pathtyper6   u   ] PNG 저장: rK   rL   rM   N)
missing_ok)parent
write_textr   chromiumlaunchnew_pagegotoresolvewait_for_timeoutmkdir
screenshotstrrQ   r\   r]   closeunlink)html_contentrc   rd   tmp_htmlrB   browserpages          r   capture_htmlr   b  s2   !!$77Hw7		 a**##*BDd)e#f		##tt-L#MDII 0 0 234IO!!$'$$TD$AOO[!1O>Cwn[MK<L<L<N<V<VWX;YY`abMMO OOtO$ MMO s$   D?B1D*>D?*D<<D??Ec            	        t        d       t        d       t        d       t        d       t        j                         } t        dt        |        d       g }t        j                         D ]Y  \  }}t        |d   z  }|j                  dd       |d	z  }|d
z  }d| }t        dd        t        d| d|d    d       t        j                         }t        | |d   ||      }	|	s$t        d| d       |j                  |ddf       |}
dD ]'  }|j                  |      }|j                         s%|}
 n t        t        t        d} ||   t!        |
j#                                     }	 t%        |||       t        j                         |z
  }t        d| d|dd       |j                  |dt!        |      f       \ t        dd        t        d       t        d        |D ]   \  }}	}|	rdnd}t        d| d| d |        " t        d!       d"d#d$d}d%d l}|j                         D ]Y  \  }\  }}t        |z  }t        |z  }|j                         r!|j+                  ||       t        d&|        Lt        d'|        [ t        d(       y # t&        $ r9}t        d| d|        |j                  |dt!        |      f       Y d }~qd }~ww xY w))Nz<============================================================u7   컨셉 21/22/23 하이브리드 이미지 생성 시작u(   
[인증] Gemini SA 토큰 획득 중...u'   [인증] 토큰 획득 성공 (길이: r7   r   Trw   zbg.jpgz
sample.png#
u   ──────────────────────────────────────────────────[r;   u    생성 시작r   r6   u$   ] 배경 생성 실패 — 건너뜀Fz	bg failed)rH   rI   z.jpegr   u
   ] 완료 (z.1fu   초)u   ] Playwright 오류: u   생성 결과 요약OKFAILz  [#z | u(   
[복사] 컨셉명 파일 복사 중...)z21-cocacola-style/sample.pngz'21-cocacola-style/21-cocacola-style.png)z22-galaxy-style/sample.pngz#22-galaxy-style/22-galaxy-style.png)z23-nike-style/sample.pngz23-nike-style/23-nike-style.pngr   u     복사 완료: u     [경고] 원본 없음: u   
모든 작업 완료.)rQ   gcloud_authget_access_tokenlenCONCEPTSitemsOUTPUT_BASEr   timern   appendrX   existsr   r'   r,   r   r   r   r`   r^   r_   )ra   resultscidcfgr   r   out_pathrd   t0ok	actual_bgrk   	candidatehtml_makersr   elapsedrm   infostatuscopy_mapr^   src_reldst_relsrcdsts                            r   mainr   {  s   	(O	
CD	(O 

56((*E	3CJ<q
ABGNN$ &1Ss8},TD18#L(C5	8*o%3x=/89YY[ K 0'5ACwBCDNNC45 	, 	C++C0I!%			 *\R'{3'I,=,=,?(@A	1x7iikB&GCwjT:;NNCs8}56G&1R 
Bvh-	
 !	VH  /RSEF83tf-./
 

56YSMH
 #+>>#3 6gwG#G#::<LLc"%cU+,.se456 

#$;  	1Cw3A378NNCA/00	1s   5AJ##	K%,.K  K%__main__)r   r   returnr   )
ra   r   rb   r   rc   r   rd   r   r   bool)r   r   rc   r   rd   r   r   None)r   r   )1__doc__
__future__r   rZ   r9   sysr   pathlibr   rR   playwright.sync_apir   r{   insertr   __file__r~   r   
gen_configr   r   r   r	   r
   r   r+   r&   r   r   r$   r   r)   r*   r   r%   r   r   rP   GEMINI_SCOPErN   rO   r   r   r'   r,   rn   r   r   __name__r@   r    r   <module>r      s   #   
    / 3tH~,,- .  o o 





	 @@DD+0  &	 $ ":)DPfK\@N"R%2M%` zF r    