import asyncio import markdown from pyppeteer import launch async def markdown_to_image(markdown_text: str, output_path: str, browser=None): """将 Markdown 转换为 HTML 并使用 Puppeteer 截图。""" try: # 将 Markdown 转换为 HTML html = markdown.markdown(markdown_text) # 使用传入的浏览器实例或创建新的 should_close_browser = False if browser is None: browser = await launch(headless=True, args=['--no-sandbox', '--disable-setuid-sandbox']) should_close_browser = True page = await browser.newPage() # 设置页面样式,使内容更美观 await page.setContent(f"""
{html}
""") # 等待内容渲染完成 await asyncio.sleep(0.5) # 获取内容尺寸并设置视口 dimensions = await page.evaluate('''() => { const container = document.querySelector('.container'); return { width: container.offsetWidth + 60, // 加上 body 的 padding height: container.offsetHeight + 60 } }''') # 设置视口大小 await page.setViewport({ 'width': dimensions['width'], 'height': dimensions['height'], 'deviceScaleFactor': 2 # 提高图片清晰度 }) # 截图,使用透明背景 await page.screenshot({ 'path': output_path, 'omitBackground': True, # 透明背景 'clip': { 'x': 0, 'y': 0, 'width': dimensions['width'], 'height': dimensions['height'] } }) # 关闭页面 await page.close() # 如果是我们创建的浏览器实例,则关闭它 if should_close_browser: await browser.close() except Exception as e: # 确保资源被释放 if 'page' in locals() and page is not None: await page.close() if should_close_browser and 'browser' in locals() and browser is not None: await browser.close() raise # 重新抛出异常以便上层处理