tomo2chin2 commited on
Commit
aeb964c
·
verified ·
1 Parent(s): 31d5798

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -33
app.py CHANGED
@@ -10,14 +10,14 @@ import tempfile
10
  import time
11
  import os
12
 
13
- def render_fullpage_screenshot_with_margin(html_code):
14
  # 1) HTMLコードを一時ファイルに保存
15
  tmp_file = tempfile.NamedTemporaryFile(suffix=".html", delete=False)
16
  tmp_path = tmp_file.name
17
  tmp_file.write(html_code.encode('utf-8'))
18
  tmp_file.close()
19
 
20
- # 2) ヘッドレスChrome(Chromium)起動オプションを設定
21
  options = Options()
22
  options.add_argument("--headless")
23
  options.add_argument("--no-sandbox")
@@ -27,54 +27,53 @@ def render_fullpage_screenshot_with_margin(html_code):
27
  try:
28
  driver = webdriver.Chrome(options=options)
29
 
30
- # 3) 初期ウィンドウサイズを設定してページを読み込む
31
  driver.set_window_size(1200, 800)
32
  driver.get("file://" + tmp_path)
33
 
34
- # 4) ページのロード完了を待機(bodyタグの存在)
35
  WebDriverWait(driver, 10).until(
36
  EC.presence_of_element_located((By.TAG_NAME, "body"))
37
  )
38
- time.sleep(2) # 外部リソースの読み込みを待つ
 
39
 
40
- # 5) スクロールバー非表示と背景色の固定(マルチライン文字列で記述)
41
  driver.execute_script(
42
- """
43
- document.documentElement.style.overflow = 'hidden';
44
- document.body.style.overflow = 'hidden';
45
- document.documentElement.style.backgroundColor = 'white';
46
- document.body.style.backgroundColor = 'white';
47
- """
48
  )
49
 
50
- # 6) ページ全体の幅と高さを、bodyとdocumentElementから取得(大きい方を使用)
51
  scroll_width = driver.execute_script(
52
- "return Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);"
 
53
  )
54
  scroll_height = driver.execute_script(
55
- "return Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);"
 
56
  )
57
 
58
- # 7) 上下左右に5%余白を確保(合計10%拡大)
59
- margin_factor = 0.05 # 5%
60
- final_width = int(scroll_width * (1 + margin_factor * 2))
61
- final_height = int(scroll_height * (1 + margin_factor * 2))
 
 
 
62
 
63
- # 8) 余白込みのウィンドウサイズに再設定
64
  driver.set_window_size(final_width, final_height)
65
- time.sleep(2) # レイアウト変化の安定待ち
66
 
67
- # 9) コンテンツを中央に配置するため、余白分だけスクロール
68
- offset_x = int(scroll_width * margin_factor)
69
- offset_y = int(scroll_height * margin_factor)
70
- driver.execute_script(f"window.scrollTo({offset_x}, {offset_y});")
71
  time.sleep(1)
72
 
73
- # 10) スクリーンショットをPNGバイナリとして取得
74
  png = driver.get_screenshot_as_png()
75
 
76
  except Exception as e:
77
- # エラー発生時は1x1の黒画像を返す
78
  return Image.new('RGB', (1, 1), color=(0, 0, 0))
79
 
80
  finally:
@@ -82,16 +81,16 @@ def render_fullpage_screenshot_with_margin(html_code):
82
  if os.path.exists(tmp_path):
83
  os.remove(tmp_path)
84
 
85
- # 11) PNGバイナリをPIL.Imageに変換して返す
86
  return Image.open(BytesIO(png))
87
 
88
- # Gradioインターフェースの定義
89
  iface = gr.Interface(
90
- fn=render_fullpage_screenshot_with_margin,
91
  inputs=gr.Textbox(lines=15, label="HTMLコード入力"),
92
- outputs=gr.Image(type="pil", label="ページ全体 + 5%余白スクリーンショット"),
93
- title="Full Page + Margin Screenshot App",
94
- description="HTMLをヘッドレスブラウザでレンダリングし、上下左右に5%余白を含めて1枚の画像として取得します。"
95
  )
96
 
97
  if __name__ == "__main__":
 
10
  import time
11
  import os
12
 
13
+ def render_fullpage_screenshot(html_code):
14
  # 1) HTMLコードを一時ファイルに保存
15
  tmp_file = tempfile.NamedTemporaryFile(suffix=".html", delete=False)
16
  tmp_path = tmp_file.name
17
  tmp_file.write(html_code.encode('utf-8'))
18
  tmp_file.close()
19
 
20
+ # 2) ヘッドレスChrome(Chromium)起動オプション
21
  options = Options()
22
  options.add_argument("--headless")
23
  options.add_argument("--no-sandbox")
 
27
  try:
28
  driver = webdriver.Chrome(options=options)
29
 
30
+ # 3) まずは適当なウィンドウサイズでページを開く
31
  driver.set_window_size(1200, 800)
32
  driver.get("file://" + tmp_path)
33
 
34
+ # 4) ページのロードを待機
35
  WebDriverWait(driver, 10).until(
36
  EC.presence_of_element_located((By.TAG_NAME, "body"))
37
  )
38
+ # 外部リソース読み込み等の安定化のため余分に待機
39
+ time.sleep(2)
40
 
41
+ # 5) スクロールバーを写したくない場合はCSSで非表示にする
42
  driver.execute_script(
43
+ "document.documentElement.style.overflow = 'hidden';"
44
+ "document.body.style.overflow = 'hidden';"
 
 
 
 
45
  )
46
 
47
+ # 6) ページ全体の幅・高さを正確に取得
48
  scroll_width = driver.execute_script(
49
+ "return Math.max("
50
+ "document.body.scrollWidth, document.documentElement.scrollWidth)"
51
  )
52
  scroll_height = driver.execute_script(
53
+ "return Math.max("
54
+ "document.body.scrollHeight, document.documentElement.scrollHeight)"
55
  )
56
 
57
+ # 7) ウィンドウサイズに2%のマージンを加える
58
+ # 端が切れやすい場合に、余白をつけて確実に表示領域を広げる
59
+ margin_width = int(scroll_width * 0.02) # 幅の2%
60
+ margin_height = int(scroll_height * 0.02) # 高さの2%
61
+
62
+ final_width = scroll_width + margin_width
63
+ final_height = scroll_height + margin_height
64
 
 
65
  driver.set_window_size(final_width, final_height)
66
+ time.sleep(2) # レイアウト再計算待ち
67
 
68
+ # 念のためページ最上部にスクロール
69
+ driver.execute_script("window.scrollTo(0, 0)")
 
 
70
  time.sleep(1)
71
 
72
+ # 8) スクリーンショットを取得
73
  png = driver.get_screenshot_as_png()
74
 
75
  except Exception as e:
76
+ # 失敗時は1x1の黒画像を返す
77
  return Image.new('RGB', (1, 1), color=(0, 0, 0))
78
 
79
  finally:
 
81
  if os.path.exists(tmp_path):
82
  os.remove(tmp_path)
83
 
84
+ # 9) PNGバイナリをPIL.Imageに変換して返す
85
  return Image.open(BytesIO(png))
86
 
87
+ # Gradioインターフェース
88
  iface = gr.Interface(
89
+ fn=render_fullpage_screenshot,
90
  inputs=gr.Textbox(lines=15, label="HTMLコード入力"),
91
+ outputs=gr.Image(type="pil", label="ページ全体のスクリーンショット"),
92
+ title="Full Page Screenshot App",
93
+ description="HTMLをヘッドレスブラウザでレンダリングし、ページ全体を1枚の画像として取得します(端に2%の余裕)。"
94
  )
95
 
96
  if __name__ == "__main__":