
    (<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d      Z ed      Zedz  d	z  Zed
z  Zedz  Zedz  ZdZdZdZddZdZddZddZddZedk(  r e        yy)u   
Sample C — 좌우 분할 솔루션형 (Split-Layout Solution) 배너 생성기
Gemini AI 배경 + HTML/CSS Playwright 오버레이 하이브리드 파이프라인
    )annotationsN)Path)sync_playwrightz&/home/jay/workspace/tools/ai-image-genz;/home/jay/workspace/output/meta-ads/angle-A/concept-samplesoutputz	v4-hybridzbg_sample_c_split.jpgzsample_c_split_template.htmlzsample-C-split.pngz0https://generativelanguage.googleapis.com/v1betaz3https://www.googleapis.com/auth/generative-languagea  Create a dramatic split-layout image for a Korean business advertisement. Left half: A stressed Korean office worker silhouette in a dark, gloomy environment. Dark gray tones (#3A3A3A, #555555), desaturated, cold blue-gray shadows, heavy atmosphere, fluorescent office lighting casting harsh downward shadows, feeling of anxiety and stagnation. Person hunched at desk or standing with slumped shoulders. Right half: A bright, hopeful business environment with a successful Korean professional. Vibrant emerald green and teal tones (#00B894, #00CEC9), warm morning sunlight streaming through floor-to-ceiling windows, modern clean office space, Seoul skyline visible, feeling of growth and success. The center dividing line should be a natural gradient blend transitioning from dark gray to emerald green. No text in image. Professional advertising photography quality. 1080x1080px square format. Cinematic, aspirational, high contrast between left darkness and right brightness.c            
     4   t         j                  j                  dt        t                     ddl} t        d       | j                  t              }t        dt        |       d       dD ]o  }t        d|        t         d| d	}d
| dd}ddt        igigdddgid}	 t        j                  |||d      }|j                  dv rt        d|j                   d       {|j                          |j#                         }|j%                  dg       }	|	st        d       |	d   j%                  di       j%                  dg       }
t'        d |
D        d      }|st        d       |d   j%                  dd       }t)        j*                  |d   d!         }t,        j/                  |       t        d"t,         d#t        |      d$d%| d&       t,        c S  t1        d'      # t        j                   $ r}t        d| d       Y d}~d}~ww xY w)(u?   Gemini API로 배경 이미지를 생성하고 저장합니다.r   Nu2   [1/3] Gemini API로 배경 이미지 생성 중...u'         SA 토큰 획득 성공 (길이: z chars))zgemini-3-pro-image-previewzgemini-3.1-flash-image-previewz)gemini-2.0-flash-preview-image-generationu         모델 시도: z/models/z:generateContentzBearer zapplication/json)AuthorizationzContent-TypepartstextresponseModalitiesIMAGETEXT)contentsgenerationConfigx   )headersjsontimeout)i  i  z      HTTP u    — 다음 모델로 시도u         HTTP 오류: 
candidatesu3         candidates 없음 — 다음 모델로 시도contentc              3  *   K   | ]  }d |v s|  yw)
inlineDataN ).0ps     [/home/jay/workspace/.worktrees/task-2057-dev2/tools/ai-image-gen/generate_sample_c_split.py	<genexpr>z&generate_background.<locals>.<genexpr>[   s     A|q/@1As   	u<         이미지 데이터 없음 — 다음 모델로 시도r   mimeTypez
image/jpegdatau         배경 저장: z (,z bytes, mime=)u>   모든 Gemini 모델 실패 — 배경 이미지 생성 불가)syspathinsertstrBASE_DIRgcloud_authprintget_service_account_tokenGEMINI_SCOPElenGEMINI_API_BASE	BG_PROMPTrequestspoststatus_coderaise_for_status	HTTPErrorr   getnextbase64	b64decodeBG_PATHwrite_bytesRuntimeError)r&   tokenmodel_idurlr   payloadresper   r   r	   
image_part	mime_typeimage_bytess                 r   generate_backgroundrB   4   s'   HHOOAs8}%	
>?11,?E	3CJ<w
GH B &%hZ01 !(3CD&ug..

 "VY$7#89:!57H I

	==gGSQD:-D$4$4#55QRS!!#
 yy{XXlB/
GI1!!)R044WbAAeA4H
PR|,00\J	&&z,'?'GHK(%gYb[1A!0DMR[Q\\]^_M&P W
XX- !! 	's*FGH	s   &A G*'G**H=HHu  <!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=1080" />
  <title>Sample C — Split Layout Solution</title>
  <style>
    @import url('file:///home/jay/.local/share/fonts/Pretendard/PretendardVariable.ttf');

    @font-face {{
      font-family: 'Pretendard';
      src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-Black.otf') format('opentype');
      font-weight: 900;
    }}
    @font-face {{
      font-family: 'Pretendard';
      src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-Bold.otf') format('opentype');
      font-weight: 700;
    }}
    @font-face {{
      font-family: 'Pretendard';
      src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-Medium.otf') format('opentype');
      font-weight: 500;
    }}
    @font-face {{
      font-family: 'Pretendard';
      src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-Regular.otf') format('opentype');
      font-weight: 400;
    }}

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

    html, body {{
      width: 1080px;
      height: 1080px;
      overflow: hidden;
      -webkit-font-smoothing: antialiased;
    }}

    body {{
      font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
      position: relative;
      background: #1a1a1a;
    }}

    /* ── 배경 레이어 ── */
    #bg-layer {{
      position: absolute;
      inset: 0;
      z-index: 0;
      background-image: url('{bg_url}');
      background-size: cover;
      background-position: center center;
      background-repeat: no-repeat;
    }}

    /* ── 좌측 어두운 오버레이 ── */
    #left-overlay {{
      position: absolute;
      top: 0;
      left: 0;
      width: 50%;
      height: 100%;
      z-index: 1;
      background: linear-gradient(
        135deg,
        rgba(30, 30, 30, 0.72) 0%,
        rgba(58, 58, 58, 0.55) 70%,
        rgba(30, 30, 30, 0.10) 100%
      );
    }}

    /* ── 우측 밝은 오버레이 ── */
    #right-overlay {{
      position: absolute;
      top: 0;
      right: 0;
      width: 50%;
      height: 100%;
      z-index: 1;
      background: linear-gradient(
        225deg,
        rgba(0, 184, 148, 0.18) 0%,
        rgba(0, 206, 201, 0.12) 60%,
        rgba(0, 184, 148, 0.05) 100%
      );
    }}

    /* ── 중앙 그라디언트 분할선 ── */
    #center-divider {{
      position: absolute;
      top: 0;
      left: calc(50% - 40px);
      width: 80px;
      height: 100%;
      z-index: 2;
      background: linear-gradient(
        90deg,
        rgba(30, 30, 30, 0.30) 0%,
        rgba(100, 100, 100, 0.15) 30%,
        rgba(0, 184, 148, 0.20) 70%,
        rgba(0, 184, 148, 0.10) 100%
      );
    }}

    /* ── 비네트 (공통) ── */
    #vignette {{
      position: absolute;
      inset: 0;
      z-index: 3;
      background: radial-gradient(
        ellipse 90% 90% at center,
        transparent 40%,
        rgba(0, 0, 0, 0.40) 100%
      );
      pointer-events: none;
    }}

    /* ── 콘텐츠 래퍼 ── */
    #content {{
      position: absolute;
      inset: 0;
      z-index: 10;
      display: flex;
      align-items: stretch;
    }}

    /* ── 좌측 텍스트 영역 ── */
    #left-text {{
      flex: 1;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      padding: 60px 40px 180px 60px;
    }}

    .left-label {{
      font-size: 22px;
      font-weight: 500;
      color: rgba(200, 200, 200, 0.70);
      letter-spacing: 0.12em;
      text-transform: uppercase;
      margin-bottom: 24px;
      text-shadow: 0 1px 8px rgba(0,0,0,0.80);
    }}

    .left-headline {{
      font-size: 80px;
      font-weight: 900;
      line-height: 1.15;
      letter-spacing: -0.02em;
      color: #FFFFFF;
      text-align: center;
      word-break: keep-all;
      text-shadow:
        0 2px 12px rgba(0, 0, 0, 0.95),
        0 4px 40px rgba(0, 0, 0, 0.85),
        0 0 80px rgba(0, 0, 0, 0.70);
      background: rgba(15, 15, 15, 0.65);
      padding: 24px 40px;
      border-radius: 16px;
      backdrop-filter: blur(12px);
      -webkit-backdrop-filter: blur(12px);
      border: 1px solid rgba(255, 255, 255, 0.12);
      box-shadow: 0 8px 32px rgba(0,0,0,0.50);
    }}

    .left-accent {{
      width: 60px;
      height: 3px;
      background: linear-gradient(90deg, rgba(136,136,136,0.80), rgba(136,136,136,0.20));
      border-radius: 2px;
      margin-top: 32px;
    }}

    /* ── 우측 텍스트 영역 ── */
    #right-text {{
      flex: 1;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      padding: 60px 60px 180px 40px;
    }}

    .right-label {{
      font-size: 22px;
      font-weight: 500;
      color: rgba(0, 220, 180, 0.85);
      letter-spacing: 0.12em;
      text-transform: uppercase;
      margin-bottom: 24px;
      text-shadow: 0 0 20px rgba(0, 184, 148, 0.60);
    }}

    .right-headline {{
      font-size: 80px;
      font-weight: 900;
      line-height: 1.15;
      letter-spacing: -0.02em;
      color: #FFFFFF;
      text-align: center;
      word-break: keep-all;
      text-shadow:
        0 2px 12px rgba(0, 0, 0, 0.90),
        0 4px 30px rgba(0, 0, 0, 0.80),
        0 0 60px rgba(0, 184, 148, 0.60);
      background: rgba(0, 90, 70, 0.65);
      padding: 24px 40px;
      border-radius: 16px;
      backdrop-filter: blur(12px);
      -webkit-backdrop-filter: blur(12px);
      border: 1px solid rgba(0, 184, 148, 0.50);
      box-shadow:
        0 8px 32px rgba(0,0,0,0.40),
        0 0 40px rgba(0,184,148,0.20);
    }}

    .right-accent {{
      width: 60px;
      height: 3px;
      background: linear-gradient(90deg, rgba(0,184,148,0.30), rgba(0,184,148,0.90));
      border-radius: 2px;
      margin-top: 32px;
    }}

    /* ── 하단 CTA 배너 ── */
    #cta-banner {{
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      z-index: 15;
      height: 130px;
      display: flex;
      align-items: center;
      justify-content: center;
      background: linear-gradient(
        90deg,
        rgba(30, 30, 30, 0.95) 0%,
        rgba(20, 60, 50, 0.95) 50%,
        rgba(0, 100, 80, 0.92) 100%
      );
      border-top: 1px solid rgba(0, 184, 148, 0.40);
    }}

    .cta-text {{
      font-size: 44px;
      font-weight: 900;
      letter-spacing: -0.01em;
      color: #FFFFFF;
      text-align: center;
      word-break: keep-all;
      text-shadow:
        0 2px 8px rgba(0, 0, 0, 0.60),
        0 0 30px rgba(0, 184, 148, 0.40);
    }}

    .cta-text .cta-accent {{
      color: #00F0C0;
      text-shadow:
        0 2px 8px rgba(0, 0, 0, 0.60),
        0 0 20px rgba(0, 240, 192, 0.70);
    }}
  </style>
</head>
<body>

  <!-- 배경 -->
  <div id="bg-layer"></div>

  <!-- 오버레이 -->
  <div id="left-overlay"></div>
  <div id="right-overlay"></div>
  <div id="center-divider"></div>
  <div id="vignette"></div>

  <!-- 콘텐츠 -->
  <div id="content">
    <!-- 좌측: 불안 -->
    <div id="left-text">
      <div class="left-headline">지금의 불안</div>
      <div class="left-accent"></div>
    </div>

    <!-- 우측: 성장 -->
    <div id="right-text">
      <div class="right-headline">내일의 성장</div>
      <div class="right-accent"></div>
    </div>
  </div>

  <!-- 하단 CTA -->
  <div id="cta-banner">
    <div class="cta-text">
      <span class="cta-accent">T.O.P</span> 사업단과 함께
    </div>
  </div>

</body>
</html>
c                    t        d       d| j                          }t        j                  |      }t        j                  |d       t        dt                t        S )uN   배경 이미지 경로를 주입한 HTML 템플릿 파일을 생성합니다.u/   [2/3] HTML 오버레이 템플릿 생성 중...file://)bg_urlzutf-8)encodingu         템플릿 저장: )r'   resolveHTML_TEMPLATEformatTEMPLATE_PATH
write_text)bg_pathrE   html_contents      r   create_html_templaterN     s[    	
;<w()*F ''v'6L\G<	$]O
45    c                    t        d       |j                  j                  dd       t               5 }|j                  j                         }	 |j                  ddd      }d| j                          }|j                  |d	       |j                  d
       |j                  t        |      d       t        d|        |j                          	 ddd       y# |j                          w xY w# 1 sw Y   yxY w)uW   Playwright 헤드리스 브라우저로 HTML을 렌더링하여 PNG로 저장합니다.u2   [3/3] Playwright로 최종 이미지 캡처 중...Tparentsexist_oki8  )widthheight)viewportrD   networkidle)
wait_untili	  png)r"   typeu         최종 이미지 저장: N)r'   parentmkdirr   chromiumlaunchnew_pagerG   gotowait_for_timeout
screenshotr$   close)template_pathoutput_pathr   browserpagetemplate_urls         r   capture_final_imageri     s    	
>?TD9		 a**##%		##tt-L#MD$]%:%:%<$=>LIIl}I=!!$'OO[!1O>3K=ABMMO  MMO s$   C4A6CC4C11C44C=c                 >   t        d       t        d       t        d       t        d       t        j                         } t        j                  dd       t        j                  dd       t               }t        |      }t        |t               t        j                         | z
  }t        j                         j                  dz  }t                t        d       t        d|dd	       t        d
t                t        d|dd       t        d       y )Nz<============================================================u5   Sample C — 좌우 분할 솔루션형 배너 생성uD   Gemini AI 배경 + HTML 오버레이 하이브리드 파이프라인TrQ   i   u   완료! 총 소요시간: z.1fu   초u   출력 파일: u   파일 크기: z.0fz KB)r'   timeTEMP_DIRr\   
OUTPUT_DIRrB   rN   ri   FINAL_OUTPUTstatst_size)
start_timerL   rd   elapsedsize_kbs        r   mainrt     s    	(O	
AB	
PQ	(OJNN4$N/TD1 "#G )1M |4iikJ&G!))D0G	G	(O	&wsm3
78	OL>
*+	OGC=
,-	(OrO   __main__)returnr   )rL   r   rv   r   )rd   r   re   r   rv   None)rv   rw   )__doc__
__future__r   r4   r   r!   rk   pathlibr   r-   playwright.sync_apir   r%   rm   rl   r6   rJ   rn   r+   r)   r,   rB   rH   rN   ri   rt   __name__r   rO   r   <module>r}      s   
 #   
    / 89OP
h,
,
,9900DD
Y 
&2Yrrj	0> zF rO   