Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -257,14 +257,13 @@ def trim_image_whitespace(image, threshold=250, padding=10):
|
|
| 257 |
|
| 258 |
# --- Core Screenshot Logic ---
|
| 259 |
def render_fullpage_screenshot(html_code: str, extension_percentage: float = 6.0,
|
| 260 |
-
|
| 261 |
"""
|
| 262 |
Renders HTML code to a full-page screenshot using Selenium.
|
| 263 |
|
| 264 |
Args:
|
| 265 |
html_code: The HTML source code string.
|
| 266 |
extension_percentage: Percentage of extra space to add vertically (e.g., 4 means 4% total).
|
| 267 |
-
is_gemini_content: True if the HTML was generated by Gemini API (requires special handling).
|
| 268 |
trim_whitespace: Whether to trim excess whitespace from the image.
|
| 269 |
|
| 270 |
Returns:
|
|
@@ -273,12 +272,6 @@ def render_fullpage_screenshot(html_code: str, extension_percentage: float = 6.0
|
|
| 273 |
tmp_path = None # 初期化
|
| 274 |
driver = None # 初期化
|
| 275 |
|
| 276 |
-
# Gemini生成コンテンツの場合、拡張率を調整
|
| 277 |
-
if is_gemini_content:
|
| 278 |
-
# 最低でも5%の拡張を確保
|
| 279 |
-
extension_percentage = max(extension_percentage, 5.0)
|
| 280 |
-
logger.info(f"Gemini生成コンテンツ用に拡張率を調整: {extension_percentage}%")
|
| 281 |
-
|
| 282 |
# 1) Save HTML code to a temporary file
|
| 283 |
try:
|
| 284 |
with tempfile.NamedTemporaryFile(suffix=".html", delete=False, mode='w', encoding='utf-8') as tmp_file:
|
|
@@ -304,9 +297,9 @@ def render_fullpage_screenshot(html_code: str, extension_percentage: float = 6.0
|
|
| 304 |
driver = webdriver.Chrome(options=options)
|
| 305 |
logger.info("WebDriver initialized.")
|
| 306 |
|
| 307 |
-
# 3)
|
| 308 |
-
initial_width = 1200
|
| 309 |
-
initial_height = 1000
|
| 310 |
driver.set_window_size(initial_width, initial_height)
|
| 311 |
file_url = "file://" + tmp_path
|
| 312 |
logger.info(f"Navigating to {file_url}")
|
|
@@ -319,9 +312,8 @@ def render_fullpage_screenshot(html_code: str, extension_percentage: float = 6.0
|
|
| 319 |
)
|
| 320 |
logger.info("Body element found. Waiting for potential resource loading...")
|
| 321 |
|
| 322 |
-
#
|
| 323 |
-
|
| 324 |
-
time.sleep(wait_time) # Wait longer for external resources/scripts
|
| 325 |
|
| 326 |
# 5) Hide scrollbars via CSS
|
| 327 |
try:
|
|
@@ -353,19 +345,14 @@ def render_fullpage_screenshot(html_code: str, extension_percentage: float = 6.0
|
|
| 353 |
document.body ? document.body.scrollHeight : 0,
|
| 354 |
document.body ? document.body.offsetHeight : 0,
|
| 355 |
document.body ? document.body.clientHeight : 0
|
| 356 |
-
),
|
| 357 |
-
visibleHeight: Math.max(
|
| 358 |
-
document.documentElement.clientHeight,
|
| 359 |
-
document.body ? document.body.clientHeight : 0
|
| 360 |
)
|
| 361 |
};
|
| 362 |
"""
|
| 363 |
dimensions = driver.execute_script(dimensions_script)
|
| 364 |
scroll_width = dimensions['width']
|
| 365 |
scroll_height = dimensions['height']
|
| 366 |
-
visible_height = dimensions.get('visibleHeight', 0)
|
| 367 |
|
| 368 |
-
logger.info(f"Detected dimensions: width={scroll_width}, height={scroll_height}
|
| 369 |
|
| 370 |
# スクロールして確認する追加の検証
|
| 371 |
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
|
|
@@ -379,11 +366,10 @@ def render_fullpage_screenshot(html_code: str, extension_percentage: float = 6.0
|
|
| 379 |
|
| 380 |
logger.info(f"After scroll check, height={scroll_height}")
|
| 381 |
|
| 382 |
-
#
|
| 383 |
-
scroll_width = max(scroll_width, 100) #
|
| 384 |
-
scroll_height = max(scroll_height, 100) #
|
| 385 |
|
| 386 |
-
# 最大値も設定(過度に大きな画像を防ぐため)
|
| 387 |
scroll_width = min(scroll_width, 2000) # 最大幅
|
| 388 |
scroll_height = min(scroll_height, 4000) # 最大高さ
|
| 389 |
|
|
@@ -391,7 +377,7 @@ def render_fullpage_screenshot(html_code: str, extension_percentage: float = 6.0
|
|
| 391 |
logger.error(f"Error getting page dimensions: {e}")
|
| 392 |
# フォールバックとしてデフォルト値を設定
|
| 393 |
scroll_width = 1200
|
| 394 |
-
scroll_height =
|
| 395 |
logger.warning(f"Falling back to dimensions: width={scroll_width}, height={scroll_height}")
|
| 396 |
|
| 397 |
# 7) Calculate adjusted height with user-specified margin
|
|
@@ -400,15 +386,14 @@ def render_fullpage_screenshot(html_code: str, extension_percentage: float = 6.0
|
|
| 400 |
adjusted_height = max(adjusted_height, scroll_height, 100) # 最小高さを確保
|
| 401 |
logger.info(f"Adjusted height calculated: {adjusted_height} (extension: {extension_percentage}%)")
|
| 402 |
|
| 403 |
-
# 8) Set window size to full page dimensions
|
| 404 |
-
adjusted_width = scroll_width
|
| 405 |
logger.info(f"Resizing window to: width={adjusted_width}, height={adjusted_height}")
|
| 406 |
driver.set_window_size(adjusted_width, adjusted_height)
|
| 407 |
logger.info("Waiting for layout stabilization after resize...")
|
| 408 |
|
| 409 |
-
#
|
| 410 |
-
|
| 411 |
-
time.sleep(stabilization_time) # Wait longer for layout stabilization
|
| 412 |
|
| 413 |
# 外部リソースの読み込み状態を確認
|
| 414 |
try:
|
|
@@ -480,9 +465,8 @@ def text_to_screenshot(text: str, extension_percentage: float, temperature: floa
|
|
| 480 |
# 1. テキストからHTMLを生成(温度パラメータも渡す)
|
| 481 |
html_code = generate_html_from_text(text, temperature)
|
| 482 |
|
| 483 |
-
# 2. HTML
|
| 484 |
-
return render_fullpage_screenshot(html_code, extension_percentage,
|
| 485 |
-
is_gemini_content=True, trim_whitespace=trim_whitespace)
|
| 486 |
except Exception as e:
|
| 487 |
logger.error(f"テキストからスクリーンショット生成中にエラーが発生: {e}", exc_info=True)
|
| 488 |
return Image.new('RGB', (1, 1), color=(0, 0, 0)) # エラー時は黒画像
|
|
@@ -545,7 +529,7 @@ async def api_render_screenshot(request: ScreenshotRequest):
|
|
| 545 |
pil_image = render_fullpage_screenshot(
|
| 546 |
request.html_code,
|
| 547 |
request.extension_percentage,
|
| 548 |
-
|
| 549 |
)
|
| 550 |
|
| 551 |
if pil_image.size == (1, 1):
|
|
@@ -608,7 +592,7 @@ def process_input(input_mode, input_text, extension_percentage, temperature, tri
|
|
| 608 |
"""入力モードに応じて適切な処理を行う"""
|
| 609 |
if input_mode == "HTML入力":
|
| 610 |
# HTMLモードの場合は既存の処理
|
| 611 |
-
return render_fullpage_screenshot(input_text, extension_percentage, trim_whitespace
|
| 612 |
else:
|
| 613 |
# テキスト入力モードの場合はGemini APIを使用
|
| 614 |
return text_to_screenshot(input_text, extension_percentage, temperature, trim_whitespace)
|
|
|
|
| 257 |
|
| 258 |
# --- Core Screenshot Logic ---
|
| 259 |
def render_fullpage_screenshot(html_code: str, extension_percentage: float = 6.0,
|
| 260 |
+
trim_whitespace: bool = True) -> Image.Image:
|
| 261 |
"""
|
| 262 |
Renders HTML code to a full-page screenshot using Selenium.
|
| 263 |
|
| 264 |
Args:
|
| 265 |
html_code: The HTML source code string.
|
| 266 |
extension_percentage: Percentage of extra space to add vertically (e.g., 4 means 4% total).
|
|
|
|
| 267 |
trim_whitespace: Whether to trim excess whitespace from the image.
|
| 268 |
|
| 269 |
Returns:
|
|
|
|
| 272 |
tmp_path = None # 初期化
|
| 273 |
driver = None # 初期化
|
| 274 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 275 |
# 1) Save HTML code to a temporary file
|
| 276 |
try:
|
| 277 |
with tempfile.NamedTemporaryFile(suffix=".html", delete=False, mode='w', encoding='utf-8') as tmp_file:
|
|
|
|
| 297 |
driver = webdriver.Chrome(options=options)
|
| 298 |
logger.info("WebDriver initialized.")
|
| 299 |
|
| 300 |
+
# 3) 初期ウィンドウサイズを設定(コンテンツの種類に関わらず同じサイズ)
|
| 301 |
+
initial_width = 1200
|
| 302 |
+
initial_height = 1000
|
| 303 |
driver.set_window_size(initial_width, initial_height)
|
| 304 |
file_url = "file://" + tmp_path
|
| 305 |
logger.info(f"Navigating to {file_url}")
|
|
|
|
| 312 |
)
|
| 313 |
logger.info("Body element found. Waiting for potential resource loading...")
|
| 314 |
|
| 315 |
+
# リソース読み込みの待機時間(コンテンツの種類に関わらず同じ待機時間)
|
| 316 |
+
time.sleep(5) # 十分な待機時間
|
|
|
|
| 317 |
|
| 318 |
# 5) Hide scrollbars via CSS
|
| 319 |
try:
|
|
|
|
| 345 |
document.body ? document.body.scrollHeight : 0,
|
| 346 |
document.body ? document.body.offsetHeight : 0,
|
| 347 |
document.body ? document.body.clientHeight : 0
|
|
|
|
|
|
|
|
|
|
|
|
|
| 348 |
)
|
| 349 |
};
|
| 350 |
"""
|
| 351 |
dimensions = driver.execute_script(dimensions_script)
|
| 352 |
scroll_width = dimensions['width']
|
| 353 |
scroll_height = dimensions['height']
|
|
|
|
| 354 |
|
| 355 |
+
logger.info(f"Detected dimensions: width={scroll_width}, height={scroll_height}")
|
| 356 |
|
| 357 |
# スクロールして確認する追加の検証
|
| 358 |
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
|
|
|
|
| 366 |
|
| 367 |
logger.info(f"After scroll check, height={scroll_height}")
|
| 368 |
|
| 369 |
+
# 最小値と最大値の設定
|
| 370 |
+
scroll_width = max(scroll_width, 100) # 最小幅
|
| 371 |
+
scroll_height = max(scroll_height, 100) # 最小高さ
|
| 372 |
|
|
|
|
| 373 |
scroll_width = min(scroll_width, 2000) # 最大幅
|
| 374 |
scroll_height = min(scroll_height, 4000) # 最大高さ
|
| 375 |
|
|
|
|
| 377 |
logger.error(f"Error getting page dimensions: {e}")
|
| 378 |
# フォールバックとしてデフォルト値を設定
|
| 379 |
scroll_width = 1200
|
| 380 |
+
scroll_height = 1000
|
| 381 |
logger.warning(f"Falling back to dimensions: width={scroll_width}, height={scroll_height}")
|
| 382 |
|
| 383 |
# 7) Calculate adjusted height with user-specified margin
|
|
|
|
| 386 |
adjusted_height = max(adjusted_height, scroll_height, 100) # 最小高さを確保
|
| 387 |
logger.info(f"Adjusted height calculated: {adjusted_height} (extension: {extension_percentage}%)")
|
| 388 |
|
| 389 |
+
# 8) Set window size to full page dimensions
|
| 390 |
+
adjusted_width = scroll_width
|
| 391 |
logger.info(f"Resizing window to: width={adjusted_width}, height={adjusted_height}")
|
| 392 |
driver.set_window_size(adjusted_width, adjusted_height)
|
| 393 |
logger.info("Waiting for layout stabilization after resize...")
|
| 394 |
|
| 395 |
+
# レイアウト安定化のための待機
|
| 396 |
+
time.sleep(4) # 統一した待機時間
|
|
|
|
| 397 |
|
| 398 |
# 外部リソースの読み込み状態を確認
|
| 399 |
try:
|
|
|
|
| 465 |
# 1. テキストからHTMLを生成(温度パラメータも渡す)
|
| 466 |
html_code = generate_html_from_text(text, temperature)
|
| 467 |
|
| 468 |
+
# 2. HTMLからスクリーンショットを生成
|
| 469 |
+
return render_fullpage_screenshot(html_code, extension_percentage, trim_whitespace)
|
|
|
|
| 470 |
except Exception as e:
|
| 471 |
logger.error(f"テキストからスクリーンショット生成中にエラーが発生: {e}", exc_info=True)
|
| 472 |
return Image.new('RGB', (1, 1), color=(0, 0, 0)) # エラー時は黒画像
|
|
|
|
| 529 |
pil_image = render_fullpage_screenshot(
|
| 530 |
request.html_code,
|
| 531 |
request.extension_percentage,
|
| 532 |
+
request.trim_whitespace
|
| 533 |
)
|
| 534 |
|
| 535 |
if pil_image.size == (1, 1):
|
|
|
|
| 592 |
"""入力モードに応じて適切な処理を行う"""
|
| 593 |
if input_mode == "HTML入力":
|
| 594 |
# HTMLモードの場合は既存の処理
|
| 595 |
+
return render_fullpage_screenshot(input_text, extension_percentage, trim_whitespace)
|
| 596 |
else:
|
| 597 |
# テキスト入力モードの場合はGemini APIを使用
|
| 598 |
return text_to_screenshot(input_text, extension_percentage, temperature, trim_whitespace)
|