
    i44                     2   d Z ddlZddl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d      Zedz  dz  Zedz  Zed	z  Zed
z  Zedz  ZdefdZdZdededefdZdededdfdZdededdfdZddZedk(  r e        yy)ux   
#15 CJK 타이포 미니멀 배너 v2 생성기
Gemini AI 배경 + Playwright HTML 오버레이 하이브리드 방식
    N)Path)sync_playwrightzE/home/jay/workspace/output/meta-ads/concept-catalog/15-cjk-typographyoutputz	v4-hybridzbg_15_cjk_v2.jpgzoverlay_15_cjk_v2.htmlzsample-v2.pngz15-cjk-typography-v2.pngreturnc                  &   t        d      } | j                         rl| j                  d      }|j                         D ]G  }|j	                  d      s|j                  dd      d   j                         j                  d      c S  t        d      )	u4   Gemini API 키를 .env 파일에서 로드합니다.z/home/jay/workspace/.envutf-8encodingzGEMINI_API_KEY==   "u*   GEMINI_API_KEY를 찾을 수 없습니다.)r   exists	read_text
splitlines
startswithsplitstripRuntimeError)env_pathcontentlines      J/home/jay/workspace/tools/ai-image-gen/_backup/gen_15_cjk_typography_v2.pyget_gemini_api_keyr   #   s    ./H$$g$6&&( 	@D01zz#q)!,224::3??	@ C
DD    zPure black minimal background, very subtle dark charcoal texture, no patterns, no people, no text, deep shadows, ultra-minimal aesthetic, slightly uneven dark surface like matte paper, 1080x1080api_keyoutput_pathc           	         t        d       d}	 t        j                  j                  dt	        t
                     ddl}|j                  d      }d| d}d| d	d
}t        d       ddt        igigdddgid}t        j                         }	 t        j                  |||d      }	|	j                          t        j                         |z
  }|	j%                         }|j'                  dg       }|s%t        dt%        j(                  |      dd         y|d   j'                  di       j'                  dg       }d}|D ]
  }d|v s|} n |t        d       y|d   j'                  d d!      }t+        j,                  |d   d"         }|j/                  |       t        d#|j0                   d$t3        |      d%d&|d'd(       y)# t        $ r d| d|  }dd	i}t        d       Y w xY w# t        j                  $ rF}
t        d|
j                  j                    d|
j                  j"                  dd         Y d}
~
yd}
~
ww xY w)*uS   Gemini AI로 배경 이미지를 생성합니다. SA 토큰 우선, API 키 폴백.u(   [배경 생성] Gemini API 호출 중...zgemini-3.1-flash-image-previewr   Nz3https://www.googleapis.com/auth/generative-languagez8https://generativelanguage.googleapis.com/v1beta/models/z:generateContentzBearer zapplication/json)AuthorizationContent-Typeu    [배경 생성] SA 토큰 사용z:generateContent?key=r   u)   [배경 생성] API 키 사용 (fallback)partstextresponseModalitiesIMAGETEXT)contentsgenerationConfigx   )headersjsontimeoutu   [배경 생성] HTTP 오류: z - i,  F
candidatesu#   [배경 생성] candidates 없음: r   
inlineDatau*   [배경 생성] 이미지 데이터 없음mimeTypez
image/jpegdatau   [배경 생성] 완료:  (,z bytes, z.1fu   초)T)printsyspathinsertstrBASE_DIRgcloud_authget_service_account_token	Exception	BG_PROMPTtimerequestspostraise_for_status	HTTPErrorresponsestatus_coder!   r)   getdumpsbase64	b64decodewrite_bytesnamelen)r   r   modelr7   tokenurlr(   payloadstartrespeelapsedr.   r+   r    
image_partpart	mime_typeimage_bytess                      r   generate_backgroundrU   5   su   	
45,E;3x=)55A
 IO_`&-eW$5GYZ01  34561GV3DEG
 IIKE}}S'M
 iikE!G99;D,+J3DJJt4DTc4J3KLMqMi,00"=EJ 4J
 :<<(,,ZFI"":l#;F#CDKK(	$[%5%5$6b[9I!8LHU\]`Taae
fgU  ;HOdeldmn!#569:;  -ajj.D.D-ESY]Z]I^H_`as*   AG )G2  G/.G/2I<IIbg_pathhtml_outputc                     d| j                          }d| d}|j                  |d       t        d|j                          y)u7   CJK 타이포 미니멀 배너 HTML을 생성합니다.file://uJ  <!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=1080" />
  <title>CJK 타이포 미니멀 배너 v2</title>
  <style>
    @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;700;900&display=swap');

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

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

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

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

    /* 어두운 오버레이 (텍스트 가독성 강화) */
    #overlay {
      position: absolute;
      inset: 0;
      z-index: 1;
      background: rgba(0, 0, 0, 0.45);
    }

    /* 메인 콘텐츠 레이어 */
    #content {
      position: absolute;
      inset: 0;
      z-index: 10;
      width: 1080px;
      height: 1080px;
    }

    /* ─── 상단 라벨 (우측 상단) ─── */
    .top-label {
      position: absolute;
      top: 60px;
      right: 72px;
      font-size: 44px;
      font-weight: 400;
      color: #AAAAAA;
      letter-spacing: 0.02em;
      font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    }

    /* ─── 초대형 키워드 ─── */
    .keyword {
      position: absolute;
      top: 240px;
      left: 72px;
      font-size: 120px;
      font-weight: 900;
      color: #FFFFFF;
      letter-spacing: -4px;
      line-height: 1.0;
      word-break: keep-all;
      font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    }

    /* ─── 골드 구분선 ─── */
    .divider {
      position: absolute;
      top: 424px; /* 240 + 120*1.0 + 32margin ≈ 392 → adjusted */
      left: 72px;
      width: 120px;
      height: 3px;
      background: #F5C518;
      border-radius: 2px;
    }

    /* ─── 헤드라인 ─── */
    .headline {
      position: absolute;
      top: 499px; /* divider_top(424) + 3 + 40margin + some buffer */
      left: 72px;
      font-size: 84px;
      font-weight: 700;
      color: #F5C518;
      line-height: 1.1;
      word-break: keep-all;
      font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    }

    /* ─── 서브카피 ─── */
    .subcopy {
      position: absolute;
      top: 605px; /* headline_top(499) + 84*1.1 + 16margin ≈ 607 */
      left: 72px;
      font-size: 64px;
      font-weight: 400;
      color: #E0E0E0;
      line-height: 1.2;
      word-break: keep-all;
      font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    }

    /* ─── CTA 버튼 ─── */
    .cta-wrap {
      position: absolute;
      bottom: 72px;
      left: 72px;
    }

    .cta {
      display: inline-block;
      background: #F5C518;
      color: #0F0F0F;
      font-size: 44px;
      font-weight: 700;
      padding: 18px 52px;
      border-radius: 50px;
      letter-spacing: -0.01em;
      line-height: 1.2;
      word-break: keep-all;
      font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    }
  </style>
</head>
<body>
  <!-- 배경 -->
  <div id="bg-layer"></div>
  <!-- 오버레이 -->
  <div id="overlay"></div>

  <!-- 콘텐츠 -->
  <div id="content">

    <!-- 상단 라벨: 우측 상단 -->
    <div class="top-label">T.O.P 사업단</div>

    <!-- 초대형 키워드 -->
    <div class="keyword">제자리걸음?</div>

    <!-- 골드 구분선 -->
    <div class="divider"></div>

    <!-- 헤드라인 -->
    <div class="headline">신입 최대 1,000만원</div>

    <!-- 서브카피 -->
    <div class="subcopy">경력직 직전연봉 50%</div>

    <!-- CTA -->
    <div class="cta-wrap">
      <div class="cta">지금 상담 신청하기 →</div>
    </div>

  </div>
</body>
</html>r   r	   u#   [HTML] 오버레이 생성 완료: N)resolve
write_textr1   rG   )rV   rW   bg_urlhtml_contents       r   create_overlay_htmlr^   v   sa     w()*F"D %X K&EmL^ <':	/0@0@/A
BCr   	html_pathc                 @   t        d       t        d      }t               5 }|j                  j	                  ddg      }	 |j                  ddd      }|j                         }d	| j                          }|j                  |d
d       |j                  d       |j                  j                  dd       |j                  t        |      d       t        d|        |j                          	 ddd       y# |j                          w xY w# 1 sw Y   yxY w)u7   Playwright로 HTML을 1080x1080 PNG로 캡처합니다.u*   [캡처] Playwright 스크린샷 시작...z'/home/jay/.local/share/fonts/Pretendardz--font-render-hinting=nonez#--disable-font-subpixel-positioning)argsi8  )widthheight)viewportrY   networkidlei0u  )
wait_untilr*   i	  Tparentsexist_okpng)r3   typeu   [캡처] 완료: N)r1   r   r   chromiumlaunchnew_contextnew_pagerZ   gotowait_for_timeoutparentmkdir
screenshotr5   close)r_   r   pretendard_dirpbrowsercontextpagefile_urls           r   capture_screenshotr|   2  s   	
67 CDN		 a**##.0UV $ 
	))TT3R)SG ##%D !!2!2!4 56HIIh=%IH !!$'$$TD$AOO[!1O>%k]34MMO+ * MMO+ s$   DB$C?%D?DDDc                     t        d       t        d       t        d       t        j                  dd       t        j                  dd       t        j                         rt        dt        j                          n<	 t               } t         t              }|st        d       t        j                          t        t        t               t        t        t                t#        j$                  t         t&               t        d	t&                t         j                         rlt         j)                         j*                  d
z  }t        d       t        d       t        dt          d|dd       t        dt&                t        d       y t        d       t        j                  d       y # t        $ r.}t        d|        t        j                  d       Y d }~\d }~ww xY w)Nz<============================================================u3   #15 CJK 타이포 미니멀 배너 v2 생성 시작Trg   u"   [배경] 기존 파일 재사용: u	   [오류] r   uI   [배경 생성 실패] 폴백: 순수 검정 배경으로 진행합니다u	   [복사] i   z=
============================================================u   생성 완료!z  1. r/   z.0fz KB)z  2. u7   [오류] 최종 파일이 생성되지 않았습니다.)r1   TEMP_DIRrs   
OUTPUT_DIRBG_PATHr   rG   r   r   r2   exitrU   touchr^   	HTML_PATHr|   FINAL_OUTPUTshutilcopy2COPY_OUTPUTstatst_size)r   rO   successsize_kbs       r   mainr   U  sm   	(O	
?@	(ONN4$N/TD1 ~~27<<.AB	(*G
 &gw7]^ MMO + y,/ LL{+	Ik]
#$ ##%--4ol^2gc]$78k]#$hGH?  	IaS/"HHQKK	s   
F6 6	G-?#G((G-__main__)r   N)__doc__rD   r)   osr   r2   r;   pathlibr   r<   playwright.sync_apir   __file__rr   r6   r   r~   r   r   r   r   r5   r   r:   boolrU   r^   r|   r   __name__ r   r   <module>r      s  
   	  
    / >  YZ
h,
'
'//	O+55EC E? 
: :4 :D :BuD uDD uDT uDx$ T d F-` zF r   