
    (<iH                       d Z ddlm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
 ddlmZmZmZ dZeZdZd	Zd
ZdZd	ZdZdZdZdZdZedz  Zedz  Zedz  Zedz  Zedz  ZdZ dZ!dZ"dZ#dZ$d:dZ%d;dZ&de de de d e d!e d"e 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 d0e d1e d2e d3e d4e d5Z(d<d6Z)d7 Z*d=d8Z+e,d9k(  r e*        yy)>u  Cell-8 서울대보험쌤 × 관리자/조직 비전 배너 생성 (v3.2 최종본)
- meta-feed-1080x1080.png  (Template B: 전체 배경 + 크림 패널)
- google-resp-1200x628.png (Template A: 좌측 텍스트 + 우측 배경)

카피 v3.2:
  Headline   : "1200% 룰 후엔 지점장 문, 좁아집니다"
  Sub-copy   : "본부 5개 | 지점 10개 | 200명+ 함께"
  Urgency    : "사무실 개설비 지원 | 조직 구축 시스템"
  Badge      : "서울대보험쌤"
  CTA        : "지점장 이직 상담 신청 →"

디자인 시스템: Cell-7 동일 (컬러만 골드 → 카라멜로 전환)
  주조색: #3E2723 (딥 브라운)
  강조색: #A0522D (카라멜)
  보조강조: #C07540
    )annotationsN)Path)sync_playwright)
CTA_MIN_PXFONT_DIRWORKSPACE_ROOT&   ,   0   :   <   4   8   L   g333333?g      ?ztools/ai-image-genz output/banners/cell-8-snu-leaderz@output/meta-ads/concept-catalog/45-oneshow-finance-luxury/bg.jpgzbg-cell8-1080.pngzbg-cell8-1200.pngz0https://generativelanguage.googleapis.com/v1betaz)gemini-2.0-flash-preview-image-generationzgemini-2.0-flash-expaa  Modern meeting room with warm natural lighting, organized documents and organizational charts on table, whiteboard with handwritten notes in background, professional but warm atmosphere, morning sunlight through window, warm brown and amber tones, intimate professional space, no people, no text, no logos. Square 1:1 format, ultra-realistic photograph.a]  Wide angle professional office space with whiteboard showing organizational structure diagram, warm desk lamp casting golden light, documents on dark wooden table, certificates and framed awards on wall, cozy professional atmosphere, warm brown and amber tones, no people, no text, no logos. Wide landscape 1.91:1 format, ultra-realistic photograph.c                     t         j                  j                  dt        t                     dd l} | j                  d      xs dS )Nr   GEMINI_API_KEY'AIzaSyDEy7IcOoTbQsI4nxfPOw3ZFbYqEL_PgFU)syspathinsertstrBASE_DIRgcloud_authget_api_key)r   s    `/home/jay/workspace/.worktrees/task-2057-dev2/tools/ai-image-gen/gen_cell8_snu_leader_banners.pyr   r   O   s3    HHOOAs8}%""#34a8aa    c                   |j                         r/|j                         j                  dkD  rt        d| d|        yt	               }dd| igigddd	gid
}t
        t        dg}|D ][  }t         d| d| }t        d| d| d       	 t        j                  ||d      }|j                  dk7  r)t        d|j                   d|j                  dd         u|j                         }
|
j                  dg       }|st        d       |d   j                  di       j                  dg       }t        d |D        d      }|s5t        d|D cg c]  }t!        |j#                                c}        t%        j&                  |d   d         }|j)                  |       t        d| d t+        |      d!d"        y y## t        $ r}	t        d|	        Y d}	~	}d}	~	ww xY wc c}w )$u>   Gemini API로 배경 이미지 생성. 성공 시 True 반환.i0u  [u   ] 기존 배경 재사용: TpartstextresponseModalitiesIMAGETEXT)contentsgenerationConfigzgemini-1.5-flashz/models/z:generateContent?key=u   ] Gemini 요청 중 (모델: z)...x   )jsontimeoutu     요청 예외: N   z  HTTP z: 
candidatesu     candidates 없음r   contentc              3  *   K   | ]  }d |v s|  yw)
inlineDataN ).0ps     r   	<genexpr>z-generate_gemini_background.<locals>.<genexpr>v   s     A|q/@1As   	u!     inlineData 없음. parts keys: r-   dataz  [OK]  (,z bytes)F)existsstatst_sizeprintr   GEMINI_MODELGEMINI_FALLBACK_MODELGEMINI_API_BASErequestspost	Exceptionstatus_coder    r'   getnextlistkeysbase64	b64decodewrite_byteslen)promptout_pathlabelapi_keypayloadmodelsmodelurlresper2   r*   r   
image_partr0   	img_bytess                   r   generate_gemini_backgroundrT   U   s	   X]]_44v=%3H:>?mG 01231GV3DEG
 13EFF  !%0EgYO%5eWDAB	==7C@D
 s"GD,,-R		$3/@AByy{XXlB/
')1!!)R044WbAAeA4H
5u6U!tAFFH~6U5VWX$$Z%=f%EF	Y'zC	N1#5W=>9< 3  	%aS)*	" 7Vs   G G-	G*G%%G*z<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=1080">
  <style>
    @font-face { font-family: 'Pretendard'; src: url('file://z}/Pretendard-Black.otf') format('opentype'); font-weight: 900; }
    @font-face { font-family: 'Pretendard'; src: url('file://z/Pretendard-ExtraBold.otf') format('opentype'); font-weight: 800; }
    @font-face { font-family: 'Pretendard'; src: url('file://z|/Pretendard-Bold.otf') format('opentype'); font-weight: 700; }
    @font-face { font-family: 'Pretendard'; src: url('file://z/Pretendard-SemiBold.otf') format('opentype'); font-weight: 600; }
    @font-face { font-family: 'Pretendard'; src: url('file://z~/Pretendard-Medium.otf') format('opentype'); font-weight: 500; }
    @font-face { font-family: 'Pretendard'; src: url('file://aQ  /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; font-family: 'Pretendard', sans-serif; word-break: keep-all; }

    .canvas { position: relative; width: 1080px; height: 1080px; overflow: hidden; }
    .bg-image { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; }
    .dark-overlay { position: absolute; inset: 0; background: rgba(62, 39, 35, 0.58); }

    .text-panel {
      position: absolute;
      top: 50%; left: 50%;
      transform: translate(-50%, -50%);
      width: 860px;
      padding: 56px 48px;
      background: rgba(255, 248, 231, 0.82);
      border-radius: 12px;
      backdrop-filter: blur(4px);
      box-shadow: 0 8px 32px rgba(62,39,35,0.25);
      display: flex; flex-direction: column;
      align-items: center;
      gap: 28px; text-align: center;
    }

    .badge {
      display: inline-block;
      background: #A0522D;
      color: #FFFFFF;
      font-size: z7px; font-weight: 700;
      height: 52px; line-height: zpx;
      padding: 0 24px;
      border-radius: 6px;
      white-space: nowrap;
      letter-spacing: -0.03em;
    }

    .headline {
      font-size: z9px; font-weight: 700;
      color: #3E2723; line-height: zr;
      letter-spacing: -1.5px;
    }
    .headline .accent { color: #A0522D; }

    .sub-copy {
      font-size: zpx; font-weight: 500;
      color: #7A3D1F;
      white-space: nowrap;
      letter-spacing: -0.02em;
    }

    .urgency {
      font-size: a  px; font-weight: 600;
      color: #7A3D1F;
      white-space: nowrap;
      letter-spacing: -0.02em;
    }

    .cta-btn {
      display: inline-block;
      background: linear-gradient(135deg, #A0522D 0%, #C07540 100%);
      color: #FFFFFF;
      font-size: z7px; font-weight: 700;
      height: 76px; line-height: uI  px;
      padding: 0 40px;
      min-width: 360px;
      width: auto;
      border-radius: 6px;
      box-shadow: 0 6px 24px rgba(160,82,45,0.40);
      white-space: nowrap;
      letter-spacing: -0.03em;
      text-align: center;
    }
  </style>
</head>
<body>
  <div class="canvas">
    <img class="bg-image" src="bg-cell8-1080.png" alt="background">
    <div class="dark-overlay"></div>
    <div class="text-panel">
      <span class="badge">서울대보험쌤</span>
      <p class="headline">1200% 룰 후엔 지점장 문,<br><span class="accent">좁아집니다</span></p>
      <p class="sub-copy">본부 5개 | 지점 10개 | 200명+ 함께</p>
      <p class="urgency">사무실 개설비 지원 | 조직 구축 시스템</p>
      <div class="cta-btn">지점장 이직 상담 신청 →</div>
    </div>
  </div>
</body>
</html>
z<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=1200">
  <style>
    @font-face { font-family: 'Pretendard'; src: url('file://aG  /Pretendard-Regular.otf') format('opentype'); font-weight: 400; }

    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
    html, body { width: 1200px; height: 628px; overflow: hidden; font-family: 'Pretendard', sans-serif; word-break: keep-all; }

    .canvas { position: relative; width: 1200px; height: 628px; overflow: hidden; }
    .bg-image { position: absolute; right: 0; top: 0; width: 65%; height: 100%; object-fit: cover; object-position: center right; }

    .gradient-overlay {
      position: absolute; inset: 0;
      background: linear-gradient(
        to right,
        rgba(62,39,35,0.97) 0%,
        rgba(62,39,35,0.95) 40%,
        rgba(62,39,35,0.85) 52%,
        rgba(62,39,35,0.50) 68%,
        rgba(62,39,35,0.15) 82%,
        transparent 100%
      );
    }

    .accent-bar {
      position: absolute;
      top: 80px; left: 0;
      width: 4px; height: 460px;
      background: linear-gradient(to bottom, #A0522D, #C07540);
      border-radius: 2px;
    }

    .text-area {
      position: absolute;
      top: 0; left: 0;
      width: 62%; height: 100%;
      padding: 48px 56px 48px 60px;
      display: flex; flex-direction: column;
      justify-content: center;
      gap: 18px;
    }

    .badge {
      display: inline-block;
      background: #A0522D;
      color: #FFFFFF;
      font-size: z7px; font-weight: 700;
      height: 48px; line-height: zpx;
      padding: 0 20px;
      border-radius: 6px;
      white-space: nowrap;
      letter-spacing: -0.03em;
      align-self: flex-start;
      margin-bottom: 6px;
    }

    .headline {
      font-size: z9px; font-weight: 700;
      color: #FFF8E7; line-height: zr;
      letter-spacing: -1.2px;
    }
    .headline .accent { color: #D4956A; }

    .sub-copy {
      font-size: zpx; font-weight: 500;
      color: #D4956A;
      text-shadow: 0 1px 3px rgba(62,39,35,0.6);
      white-space: nowrap;
      letter-spacing: -0.02em;
    }

    .urgency {
      font-size: aH  px; font-weight: 500;
      color: rgba(255, 248, 231, 0.82);
      text-shadow: 0 1px 3px rgba(62,39,35,0.6);
      white-space: nowrap;
      letter-spacing: -0.02em;
    }

    .cta-btn {
      display: inline-block;
      background: linear-gradient(135deg, #A0522D 0%, #C07540 100%);
      color: #FFFFFF;
      font-size: z7px; font-weight: 700;
      height: 56px; line-height: u  px;
      padding: 0 32px;
      min-width: 220px;
      width: auto;
      border-radius: 6px;
      box-shadow: 0 4px 16px rgba(160,82,45,0.40);
      white-space: nowrap;
      letter-spacing: -0.03em;
      align-self: flex-start;
      text-align: center;
      margin-top: 14px;
    }
  </style>
</head>
<body>
  <div class="canvas">
    <img class="bg-image" src="bg-cell8-1200.png" alt="background">
    <div class="gradient-overlay"></div>
    <div class="accent-bar"></div>
    <div class="text-area">
      <span class="badge">서울대보험쌤</span>
      <p class="headline">1200% 룰 후엔 지점장 문,<br><span class="accent">좁아집니다</span></p>
      <p class="sub-copy">본부 5개 | 지점 10개 | 200명+ 함께</p>
      <p class="urgency">사무실 개설비 지원 | 조직 구축 시스템</p>
      <div class="cta-btn">지점장 이직 상담 신청 →</div>
    </div>
  </div>
</body>
</html>
c           
        t               5 }|j                  j                         }	 |j                  ||d      }|j	                  d| j                          d       |j                  d       |j                  t        |      ddd||d	
       |j                         j                  dz  }t        d|j                   d| d       |j                          	 ddd       y# |j                          w xY w# 1 sw Y   yxY w)u-   Playwright로 HTML을 PNG로 캡처합니다.)widthheight)viewportzfile://networkidle)
wait_untili	  pngr   )xyrV   rW   )r   typeclip   u     [렌더링 완료] r3    KB)N)r   chromiumlaunchnew_pagegotoresolvewait_for_timeout
screenshotr   r6   r7   r8   nameclose)	html_pathrV   rW   rI   r0   browserpagesize_kbs           r   render_html_to_pngro   p  s    		 a**##%	##u-O#PDII	 1 1 345-IP!!$'OO]1uG  
 mmo--5G)(--7)4HIMMO  MMO s#   C;B%C&C;&C88C;;Dc                 ,   t        d       t        d       t        d       t        j                  dd       t        d       t        t        t
        d      } | stt        dt                dd l}t        j                         r-|j                  t        t
               t        d	t
                nt        d
       t        t
        ddd       t        t        t        d      }|stt        dt                dd l}t        j                         r-|j                  t        t               t        d	t                nt        d
       t        t        ddd       t        d       t        dz  }t        dz  }|j                  t        d       t        d|        |j                  t        d       t        d|        t        d       t        dz  }t        dz  }t        d       t!        |dd|       t        d       t!        |dd|       t        d       t        d       t
        t        ||||g}|D ]O  }|j                         r.t        d| d|j#                         j$                  dz   d        At        d!| d"       Q t        d       y )#Nz<============================================================uB   Cell-8 서울대보험쌤 × 관리자/조직 비전 배너 생성T)parentsexist_oku!   
[Step 1] 배경 이미지 생성u   1080x1080 배경u#     Gemini 실패 → 폴백 사용: r   u     폴백 복사 완료: u;     폴백도 없음 → 브라운 단색 배경으로 대체i8  z#3E2723u   1200x628 배경i  it  u   
[Step 2] HTML 파일 저장zmeta-feed-1080x1080.htmlzgoogle-resp-1200x628.htmlzutf-8)encodingu
     저장: u   
[Step 3] Playwright 렌더링zmeta-feed-1080x1080.pngzgoogle-resp-1200x628.pngu     1080x1080 렌더링 중...u     1200x628 렌더링 중...z=
============================================================u   완료!z  OK  z  (r`   ra   z  !!  u
     (없음))r8   
OUTPUT_DIRmkdirrT   PROMPT_1080BG_1080_PATHFALLBACK_BGshutilr5   copy2create_solid_bgPROMPT_1200BG_1200_PATH
write_text	HTML_1080	HTML_1200ro   r6   r7   )	ok_1080ry   ok_1200html_1080_pathhtml_1200_pathout_1080out_1200filesfs	            r   mainr     s;   	(O	
NO	(OTD1 

./(lDVWG3K=ABLLl3,\N;< OPL$i@(lDUVG3K=ABLLl3,\N;<OPL$Y? 

)*"<<N"==Ni':	J~&
'(i':	J~&
'( 

+,55H66H	
()~tT8<	
'(~tS(; 
/	)<S[\E *88:F1#S!1!1T!9 :$?@F1#Z()	*
 
(Or   c                    d| d| d| d| d| d}| j                  d      }|j                  |       ddl}|j                  d	t	        |      t	        |       gd
       |j                  d
       y)u=   PIL 없이 SVG→PNG로 단색 배경 생성 (최후 수단).z/<svg xmlns="http://www.w3.org/2000/svg" width="z
" height="z"><rect width="z" fill="z	"/></svg>z.svgr   NconvertT)check)
missing_ok)with_suffixr~   
subprocessrunr   unlink)r   whcolorsvgsvg_pathr   s          r   r{   r{     s    ;A3j?[\Z]]ghigjjrsxry  zC  DC'HNNIs8}c$i8NEOOtO$r   __main__)returnr   )rH   r   rI   r   rJ   r   r   bool)
rk   r   rV   intrW   r   rI   r   r   None)
r   r   r   r   r   r   r   r   r   r   )-__doc__
__future__r   rD   r   timepathlibr   r<   playwright.sync_apir   
gen_configr   r   r   
_SIZE_38PX_CTA_PX
_SIZE_44PX
_SIZE_48PX
_SIZE_58PX
_SIZE_60PX_LH_48PX_LH_52PX_LH_56PX_LH_76PX_LH_1_2_LH_1_25r   rt   rx   rw   r}   r;   r9   r:   rv   r|   r   rT   r   r   ro   r   r{   __name__r.   r   r   <module>r      sS  " #  
    / ; ; 






 00@@
aa////D:. 5 @ b+d? @Hj I??Gj I??Gj I??Gj I??Gj I??Gj I8  ""* ,  $$,: .    
  ""* ,Ud	T? @Hj I??Gj I??Gj I??Gj I??Gj I??Gj +IV  ""* 
,  $$+9 -      ""* ,{z	~*FR% zF r   