File size: 3,751 Bytes
b26e489
 
e0538f9
e6532da
 
 
da755ee
 
e6532da
 
 
26b8c3d
ccc6222
 
 
 
 
e6532da
 
 
 
 
 
aeb964c
e6532da
 
 
 
 
26b8c3d
 
e6532da
da755ee
ccc6222
e6532da
 
da755ee
aeb964c
e6532da
 
 
ccc6222
da755ee
ccc6222
31d5798
aeb964c
 
31d5798
e6532da
ccc6222
e6532da
ccc6222
e6532da
 
ccc6222
31d5798
 
ccc6222
 
 
 
a1a59cd
ccc6222
31d5798
ccc6222
aeb964c
31d5798
 
ccc6222
31d5798
 
 
ccc6222
31d5798
 
 
 
 
 
 
 
ccc6222
31d5798
aeb964c
ccc6222
 
59a7627
ccc6222
aeb964c
ccc6222
 
31d5798
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import gradio as gr
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from PIL import Image
from io import BytesIO
import tempfile
import time
import os

def render_fullpage_screenshot(html_code, extension_percentage):
    """
    html_code: HTMLのソースコード文字列
    extension_percentage: 上下に追加する余裕の% (例: 4なら合計4%の余裕)
    """
    # 1) HTMLコードを一時ファイルに保存
    tmp_file = tempfile.NamedTemporaryFile(suffix=".html", delete=False)
    tmp_path = tmp_file.name
    tmp_file.write(html_code.encode('utf-8'))
    tmp_file.close()

    # 2) ヘッドレスChrome(Chromium)起動オプション
    options = Options()
    options.add_argument("--headless")
    options.add_argument("--no-sandbox")
    options.add_argument("--disable-dev-shm-usage")
    options.add_argument("--force-device-scale-factor=1")

    try:
        driver = webdriver.Chrome(options=options)

        # 3) 初期ウィンドウサイズでページを読み込む
        driver.set_window_size(1200, 800)
        driver.get("file://" + tmp_path)

        # 4) ページのロードを待機
        WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.TAG_NAME, "body"))
        )
        time.sleep(2)  # 外部リソースの読み込み待機

        # 5) スクロールバーがキャプチャに写らないようCSSで非表示
        driver.execute_script(
            "document.documentElement.style.overflow = 'hidden';"
            "document.body.style.overflow = 'hidden';"
        )

        # 6) ページ全体の幅・高さを正確に取得 (bodyとdocumentElementの両方から)
        scroll_width = driver.execute_script(
            "return Math.max(document.body.scrollWidth, document.documentElement.scrollWidth)"
        )
        scroll_height = driver.execute_script(
            "return Math.max(document.body.scrollHeight, document.documentElement.scrollHeight)"
        )

        # 7) 上下方向にだけユーザー指定の余裕(%)を加えた高さを計算
        adjusted_height = int(scroll_height * (1 + extension_percentage/100))
        
        # 8) ウィンドウサイズを、幅はそのまま、縦はadjusted_heightに変更
        driver.set_window_size(scroll_width, adjusted_height)
        time.sleep(2)  # レイアウトの安定化待機

        # 念のため最上部にスクロール
        driver.execute_script("window.scrollTo(0, 0)")
        time.sleep(1)

        # 9) スクリーンショット取得
        png = driver.get_screenshot_as_png()

    except Exception as e:
        # エラー時は1x1の黒画像を返す
        return Image.new('RGB', (1, 1), color=(0, 0, 0))
    finally:
        driver.quit()
        if os.path.exists(tmp_path):
            os.remove(tmp_path)

    return Image.open(BytesIO(png))

# Gradioインターフェースの定義
iface = gr.Interface(
    fn=render_fullpage_screenshot,
    inputs=[
        gr.Textbox(lines=15, label="HTMLコード入力"),
        gr.Slider(minimum=0, maximum=20, step=1.0, value=8, label="上下高さ拡張率(%)")
    ],
    outputs=gr.Image(type="pil", label="ページ全体のスクリーンショット"),
    title="Full Page Screenshot App (高さ拡張調整可能)",
    description="HTMLをヘッドレスブラウザでレンダリングし、ページ全体を1枚の画像として取得します。上下のみユーザー指定の余裕(%)を追加します。"
)

if __name__ == "__main__":
    iface.launch()