Markdown 转精美图片 将 Markdown 内容渲染为精美的分享海报图片,适合微信、小红书、微博等平台。 核心特性 - 固定 3:4 比例 (1080×1440 像素) - 自动分页 - 内容较多时生成多张图片 - 智能 SVG 头图 - 根据主题关键词自动生成相应风格的手绘线条图 - 智能标题 - 自动提取嘉宾名和主题,格式为「嘉宾:主题」 - 白色背景 + 大字体 - 清晰易读,专业排版 - 自适应布局 - 内容均匀分布,减少留白 - 宽字间距行间距 - 参考优秀海报排版 快速开始 基本用法 参数说明 | 参数 | 说明 | 默认值 | |------|------|--------| | , | Markdown 文件路径 | 必填 | | , | 输出目录 | | | , | 图片宽度(像素) | | | | 每页显示条目数 | | 输出规格 - 比例 : 固定 3:4(1080×1440 像素) - 格式 : PNG - 分页 : 自动根据内容生成多张图片 - 命名 : , , ... - 保存位置 : 默认 (MMDD 为当日日期) 智能 SVG 头图 根据文章主题自动生成不同风格的 SVG 装饰图: | 主题关键词 | 生成的 SVG 风格 | |-----------|----------------| | 、 、 | 神经网络节点 → 大脑 → 对话泡泡…

\n \n # 先扫描全文找 YouTube URL\n youtube_pattern = r'(https?://(?:www\\.)?(?:youtube\\.com/watch\\?v=|youtu\\.be/)[\\w-]+)'\n for line in lines:\n yt_match = re.search(youtube_pattern, line)\n if yt_match:\n result['youtube_url'] = yt_match.group(1)\n break\n \n for i, line in enumerate(lines):\n line = line.strip()\n \n if line.startswith('# 精华') or line.startswith('# 精彩'):\n break\n \n if line == '---':\n if found_first_point:\n break\n continue\n \n if not line:\n continue\n \n # 主标题 - 保留原始标题\n if line.startswith('# ') and not result['title']:\n title = line[2:].strip()\n result['title'] = title # 使用原始标题\n \n # 提取冒号后的短标题(用于续页)\n # 先去掉日期前缀再取冒号后内容\n title_without_date = re.sub(r'^\\d{4}[::]\\s*', '', title)\n if ':' in title_without_date:\n result['short_title'] = title_without_date.split(':', 1)[1].strip()\n elif ':' in title_without_date:\n result['short_title'] = title_without_date.split(':', 1)[1].strip()\n else:\n result['short_title'] = title_without_date[:20] + '...' if len(title_without_date) > 20 else title_without_date\n continue\n \n # 核心观点\n match = re.match(point_pattern, line)\n if match:\n found_first_point = True\n \n if point_buffer:\n result['points'].append({\n 'number': point_buffer[0],\n 'title': point_buffer[1],\n 'content': ' '.join(point_buffer[2:]) if len(point_buffer) > 2 else ''\n })\n point_buffer = []\n \n num = match.group(1)\n title_text = match.group(2).strip()\n \n # 分离标题和内容\n title_parts = re.split(r'[。!?]', title_text, 1)\n if len(title_parts) > 1 and title_parts[1].strip():\n point_buffer = [num, title_parts[0] + '。', title_parts[1].strip()]\n else:\n point_buffer = [num, title_text]\n else:\n if found_first_point and point_buffer:\n if not line.startswith('#'):\n if len(point_buffer) == 2:\n point_buffer.append(line)\n else:\n point_buffer[-1] += ' ' + line\n elif not found_first_point:\n if line.startswith('> '):\n result['intro'] = line[2:].strip()\n elif not line.startswith('#') and not re.search(youtube_pattern, line):\n intro_lines.append(line)\n \n if point_buffer:\n result['points'].append({\n 'number': point_buffer[0],\n 'title': point_buffer[1],\n 'content': ' '.join(point_buffer[2:]) if len(point_buffer) > 2 else ''\n })\n \n if not result['intro'] and intro_lines:\n result['intro'] = ' '.join([l for l in intro_lines if not l.startswith('这期播客')][:2])\n \n return result\n\n\ndef process_markdown_text(text: str) -> str:\n \"\"\"处理 Markdown 格式\"\"\"\n text = re.sub(r'\\*\\*(.+?)\\*\\*', r'\u003cstrong>\\1\u003c/strong>', text)\n text = re.sub(r'__(.+?)__', r'\u003cstrong>\\1\u003c/strong>', text)\n text = re.sub(r'(?\u003c!\\*)\\*([^*]+)\\*(?!\\*)', r'\u003cem>\\1\u003c/em>', text)\n text = re.sub(r'(?\u003c!_)_([^_]+)_(?!_)', r'\u003cem>\\1\u003c/em>', text)\n text = re.sub(r'`([^`]+)`', r'\u003ccode>\\1\u003c/code>', text)\n return text\n\n\ndef generate_html_content(data: dict, page_num: int = 0, total_pages: int = 1, \n cover_image_url: str = None, show_intro: bool = False,\n is_last_page: bool = False) -> str:\n \"\"\"生成 HTML 内容\"\"\"\n html_parts = []\n \n has_cover = cover_image_url and page_num == 0\n \n if page_num == 0:\n if data['title']:\n title = process_markdown_text(data['title'])\n html_parts.append(f\"\u003ch1>{title}\u003c/h1>\")\n \n if show_intro and data['intro']:\n intro = process_markdown_text(data['intro'])\n html_parts.append(f'\u003cdiv class=\"intro\">{intro}\u003c/div>')\n \n html_parts.append('\u003cdiv class=\"transition\">▼ 核心观点\u003c/div>')\n else:\n # 续页使用短标题\n if data['short_title']:\n short_title = process_markdown_text(data['short_title'])\n html_parts.append(f\"\u003ch2>{short_title}(续)\u003c/h2>\")\n \n html_parts.append('\u003cdiv class=\"points-container\">')\n \n for point in data['points']:\n title_html = process_markdown_text(point['title'])\n content_html = ''\n if point.get('content'):\n content_html = f'\u003cdiv class=\"point-content\">{process_markdown_text(point[\"content\"])}\u003c/div>'\n \n html_parts.append(f'''\n \u003cdiv class=\"point\">\n \u003cdiv class=\"point-header\">\n \u003cspan class=\"point-number\">{point[\"number\"]}.\u003c/span>\n \u003cspan class=\"point-title\">{title_html}\u003c/span>\n \u003c/div>\n {content_html}\n \u003c/div>\n ''')\n \n html_parts.append('\u003c/div>')\n \n content = '\\n'.join(html_parts)\n \n return get_html_template(content, page_num, total_pages, \n cover_image_url if page_num == 0 else None,\n is_last_page)\n\n\nasync def get_youtube_thumbnail(youtube_url: str) -> str:\n \"\"\"获取 YouTube 封面图\"\"\"\n if not youtube_url:\n return None\n \n patterns = [\n r'youtube\\.com/watch\\?v=([\\w-]+)',\n r'youtu\\.be/([\\w-]+)',\n ]\n \n for pattern in patterns:\n match = re.search(pattern, youtube_url)\n if match:\n return f\"https://img.youtube.com/vi/{match.group(1)}/maxresdefault.jpg\"\n \n return None\n\n\nasync def render_to_image(html_content: str, output_path: str):\n \"\"\"渲染为图片 - 自适应内容高度\"\"\"\n async with async_playwright() as p:\n browser = await p.chromium.launch(channel='chrome')\n page = await browser.new_page(viewport={'width': CARD_WIDTH, 'height': CARD_HEIGHT})\n \n await page.set_content(html_content)\n await page.wait_for_timeout(1500)\n \n # 获取实际内容高度\n body_height = await page.evaluate('document.body.scrollHeight')\n \n # 确保最小高度为 CARD_HEIGHT,但如果内容更多则扩展\n actual_height = max(CARD_HEIGHT, body_height)\n \n # 重新设置视口并截图\n await page.set_viewport_size({'width': CARD_WIDTH, 'height': actual_height})\n await page.wait_for_timeout(300)\n \n await page.screenshot(path=output_path, clip={\n 'x': 0, 'y': 0,\n 'width': CARD_WIDTH, 'height': actual_height\n })\n \n await browser.close()\n \n return actual_height\n\n\ndef get_output_dir(md_file: str, base_dir: str = None) -> Path:\n \"\"\"生成输出目录\"\"\"\n if base_dir is None:\n base_dir = '/Users/ugreen/Documents/obsidian/attachments'\n \n filename = Path(md_file).stem\n match = re.match(r'^(\\d{4})-(.+)

Markdown 转精美图片 将 Markdown 内容渲染为精美的分享海报图片,适合微信、小红书、微博等平台。 核心特性 - 固定 3:4 比例 (1080×1440 像素) - 自动分页 - 内容较多时生成多张图片 - 智能 SVG 头图 - 根据主题关键词自动生成相应风格的手绘线条图 - 智能标题 - 自动提取嘉宾名和主题,格式为「嘉宾:主题」 - 白色背景 + 大字体 - 清晰易读,专业排版 - 自适应布局 - 内容均匀分布,减少留白 - 宽字间距行间距 - 参考优秀海报排版 快速开始 基本用法 参数说明 | 参数 | 说明 | 默认值 | |------|------|--------| | , | Markdown 文件路径 | 必填 | | , | 输出目录 | | | , | 图片宽度(像素) | | | | 每页显示条目数 | | 输出规格 - 比例 : 固定 3:4(1080×1440 像素) - 格式 : PNG - 分页 : 自动根据内容生成多张图片 - 命名 : , , ... - 保存位置 : 默认 (MMDD 为当日日期) 智能 SVG 头图 根据文章主题自动生成不同风格的 SVG 装饰图: | 主题关键词 | 生成的 SVG 风格 | |-----------|----------------| | 、 、 | 神经网络节点 → 大脑 → 对话泡泡…

, filename)\n if match:\n date_str = match.group(1)\n title = match.group(2)\n else:\n date_str = datetime.now().strftime('%m%d')\n title = filename\n \n title = re.sub(r'[\u003c>:\"/\\\\|?*]', '-', title)\n output_dir = Path(base_dir) / f\"{date_str}-{title}\"\n output_dir.mkdir(parents=True, exist_ok=True)\n \n return output_dir\n\n\nasync def convert_md_to_images(md_file: str, output_dir: str = None, \n points_per_page: int = 4,\n with_cover: bool = True) -> list:\n \"\"\"转换 Markdown 为图片\"\"\"\n with open(md_file, 'r', encoding='utf-8') as f:\n content = f.read()\n \n data = parse_content_to_points(content)\n \n if not data['points']:\n print(\"警告:未能解析出核心观点\")\n return []\n \n # YouTube 封面图\n cover_url = None\n if with_cover and data['youtube_url']:\n cover_url = await get_youtube_thumbnail(data['youtube_url'])\n if cover_url:\n print(f\"📷 检测到 YouTube 链接,使用视频封面\")\n \n # 智能分页(字体放大后每页观点数减少)\n has_intro = bool(data['intro'])\n total_points = len(data['points'])\n \n if cover_url:\n first_page_capacity = 2 # 有封面图时首页只放2个观点\n else:\n first_page_capacity = 2 if has_intro else points_per_page\n \n if total_points \u003c= first_page_capacity:\n total_pages = 1\n page_distribution = [total_points]\n else:\n remaining = total_points - first_page_capacity\n extra_pages = (remaining + points_per_page - 1) // points_per_page\n total_pages = 1 + extra_pages\n \n if extra_pages == 1:\n page_distribution = [first_page_capacity, remaining]\n else:\n base_per_page = remaining // extra_pages\n extra_points = remaining % extra_pages\n \n page_distribution = [first_page_capacity]\n for i in range(extra_pages):\n points = base_per_page + (1 if i \u003c extra_points else 0)\n page_distribution.append(points)\n \n if output_dir is None:\n output_dir = get_output_dir(md_file)\n else:\n output_dir = Path(output_dir)\n output_dir.mkdir(parents=True, exist_ok=True)\n \n output_files = []\n current_point = 0\n \n print(f\"📊 分页方案: {page_distribution} (共 {total_points} 个观点)\")\n \n for page_num in range(total_pages):\n page_points = page_distribution[page_num]\n is_last_page = (page_num == total_pages - 1)\n \n page_data = {\n 'title': data['title'],\n 'short_title': data['short_title'],\n 'intro': data['intro'],\n 'points': data['points'][current_point:current_point + page_points]\n }\n \n for i, point in enumerate(page_data['points']):\n point['number'] = str(current_point + i + 1)\n \n html_content = generate_html_content(\n page_data, page_num, total_pages,\n cover_url if page_num == 0 else None,\n show_intro=(page_num == 0 and has_intro),\n is_last_page=is_last_page\n )\n \n output_path = output_dir / f'page-{page_num + 1}.png'\n actual_height = await render_to_image(html_content, str(output_path))\n output_files.append(str(output_path))\n \n height_note = f\" (高度: {actual_height}px)\" if actual_height > CARD_HEIGHT else \"\"\n print(f\"✅ 生成第 {page_num + 1}/{total_pages} 页: {output_path}{height_note}\")\n \n current_point += page_points\n \n return output_files\n\n\ndef main():\n parser = argparse.ArgumentParser(description='Markdown 转知识卡片')\n parser.add_argument('input', help='Markdown 文件路径')\n parser.add_argument('-o', '--output', help='输出目录')\n parser.add_argument('-p', '--points-per-page', type=int, default=4,\n help='每页观点数(默认: 4)')\n parser.add_argument('--no-cover', action='store_true', help='不使用封面图')\n parser.add_argument('--author', help='水印作者')\n \n args = parser.parse_args()\n \n if not os.path.exists(args.input):\n print(f\"错误:文件不存在: {args.input}\")\n return 1\n \n global WATERMARK_AUTHOR\n if args.author:\n WATERMARK_AUTHOR = args.author\n \n output_files = asyncio.run(convert_md_to_images(\n args.input,\n args.output,\n args.points_per_page,\n not args.no_cover\n ))\n \n if output_files:\n print(f\"\\n🎉 完成!共生成 {len(output_files)} 张图片\")\n print(f\"📁 保存目录: {Path(output_files[0]).parent}\")\n \n return 0\n\n\nif __name__ == '__main__':\n exit(main())\n","content_type":"text/x-python; charset=utf-8","language":"python","size":19590,"content_sha256":"31b31d85d54d76e1efbb64677cd4e09edda204158fd75d671843f265a3d554a0"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Markdown 转精美图片","type":"text"}]},{"type":"paragraph","content":[{"text":"将 Markdown 内容渲染为精美的分享海报图片,适合微信、小红书、微博等平台。","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"核心特性","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"固定 3:4 比例","type":"text","marks":[{"type":"strong"}]},{"text":"(1080×1440 像素)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"自动分页","type":"text","marks":[{"type":"strong"}]},{"text":" - 内容较多时生成多张图片","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"智能 SVG 头图","type":"text","marks":[{"type":"strong"}]},{"text":" - 根据主题关键词自动生成相应风格的手绘线条图","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"智能标题","type":"text","marks":[{"type":"strong"}]},{"text":" - 自动提取嘉宾名和主题,格式为「嘉宾:主题」","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"白色背景 + 大字体","type":"text","marks":[{"type":"strong"}]},{"text":" - 清晰易读,专业排版","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"自适应布局","type":"text","marks":[{"type":"strong"}]},{"text":" - 内容均匀分布,减少留白","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"宽字间距行间距","type":"text","marks":[{"type":"strong"}]},{"text":" - 参考优秀海报排版","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"快速开始","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"基本用法","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# 转换 Markdown 文件为图片(自动分页)\npython3 scripts/md_to_image.py --file /path/to/content.md\n\n# 指定输出目录\npython3 scripts/md_to_image.py --file /path/to/content.md --output-dir /path/to/output\n\n# 调整每页条目数\npython3 scripts/md_to_image.py --file /path/to/content.md --items-per-page 4","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"参数说明","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"参数","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"说明","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"默认值","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--file","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"-f","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Markdown 文件路径","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"必填","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--output-dir","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"-o","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"输出目录","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"attachments/MMDD","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--width","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"-w","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"图片宽度(像素)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1080","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--items-per-page","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"每页显示条目数","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"5","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"输出规格","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"比例","type":"text","marks":[{"type":"strong"}]},{"text":": 固定 3:4(1080×1440 像素)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"格式","type":"text","marks":[{"type":"strong"}]},{"text":": PNG","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"分页","type":"text","marks":[{"type":"strong"}]},{"text":": 自动根据内容生成多张图片","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"命名","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"page_1.png","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"page_2.png","type":"text","marks":[{"type":"code_inline"}]},{"text":", ...","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"保存位置","type":"text","marks":[{"type":"strong"}]},{"text":": 默认 ","type":"text"},{"text":"attachments/MMDD","type":"text","marks":[{"type":"code_inline"}]},{"text":"(MMDD 为当日日期)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"智能 SVG 头图","type":"text"}]},{"type":"paragraph","content":[{"text":"根据文章主题自动生成不同风格的 SVG 装饰图:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"主题关键词","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"生成的 SVG 风格","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"AI","type":"text","marks":[{"type":"code_inline"}]},{"text":"、","type":"text"},{"text":"AGI","type":"text","marks":[{"type":"code_inline"}]},{"text":"、","type":"text"},{"text":"通用","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"神经网络节点 → 大脑 → 对话泡泡","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"开源","type":"text","marks":[{"type":"code_inline"}]},{"text":"、","type":"text"},{"text":"open source","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"开源符号 → 代码括号 → 分享图标","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"其他(默认)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"麦克风 → 声波 → 人物对话","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"SVG 特点:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"手绘风格,黑色线条白底","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"宽幅 16:9 比例","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"140px 高度,居中显示","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"底部带主题文字标签","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"智能标题提取","type":"text"}]},{"type":"paragraph","content":[{"text":"自动从 Markdown 元信息中提取嘉宾和主题:","type":"text"}]},{"type":"paragraph","content":[{"text":"输入格式","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"# 播客名称\n\n> **嘉宾**: Sebastian Raschka(LLM研究员)\n> **主题**: 2025年AI技术趋势","type":"text"}]},{"type":"paragraph","content":[{"text":"输出标题","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"},{"text":"Sebastian Raschka:2025年AI技术趋势","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Markdown 格式处理","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"格式","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"渲染效果","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"# 标题","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"自动提取并组合为「嘉宾:主题」","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"> **嘉宾**: ...","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"提取嘉宾名(移除 ","type":"text"},{"text":"**","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"> **主题**: ...","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"提取主题内容","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"**加粗**","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"红色加粗文字(移除 ","type":"text"},{"text":"**","type":"text","marks":[{"type":"code_inline"}]},{"text":" 标记)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1、2、3、","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"红色圆形数字编号","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"引用内容\"","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"蓝色高亮引用","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"工作流程","type":"text"}]},{"type":"paragraph","content":[{"text":"当用户请求将 Markdown 转为图片时:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"确定输入内容","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"如果用户指定了文件路径,使用该文件","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"如果用户当前打开了 Markdown 文件,默认使用该文件","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"自动处理","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"提取嘉宾和主题生成标题","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"根据主题关键词生成相应 SVG 头图","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"提取短版摘要(","type":"text"},{"text":"📱 短版摘要","type":"text","marks":[{"type":"code_inline"}]},{"text":" 部分)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"移除所有 ","type":"text"},{"text":"**","type":"text","marks":[{"type":"code_inline"}]},{"text":" markdown 标记,转为真正的加粗样式","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"根据条目数量自动分页","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"输出结果","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"返回所有图片路径给用户","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"图片保存在 ","type":"text"},{"text":"attachments/MMDD","type":"text","marks":[{"type":"code_inline"}]},{"text":" 目录","type":"text"}]}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"常见用法","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"用户说","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"操作","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"「把这个转成图片」","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"转换当前打开的 Markdown 文件","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"「生成分享海报」","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"同上","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"「这个播客摘要转图片」","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"转换播客摘要文件","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"「Markdown 转图片」","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"同上","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"依赖","type":"text"}]},{"type":"paragraph","content":[{"text":"脚本依赖以下 Python 包:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"playwright","type":"text","marks":[{"type":"code_inline"}]},{"text":" - 浏览器自动化渲染","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"markdown","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Markdown 解析","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"requests","type":"text","marks":[{"type":"code_inline"}]},{"text":" - 网络请求(备用)","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"首次使用需安装:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"pip3 install playwright markdown requests\nplaywright install chromium","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"更新日志","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"v1.1 (2026-02-01)","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ 智能 SVG 头图:根据主题关键词自动生成相应风格","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ 智能标题:自动提取「嘉宾:主题」格式","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ 移除 ","type":"text"},{"text":"**","type":"text","marks":[{"type":"code_inline"}]},{"text":" 标记:元信息和正文中的 markdown 加粗正确转换","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ SVG 更大更醒目:140px 高度,600px 宽","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ 优化排版:更大字体、更宽间距、自适应布局","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"v1.0 (2026-02-01)","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"初始版本","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"固定 3:4 比例","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"自动分页","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"白色背景设计","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"markdown-to-image","author":"@skillopedia","source":{"stars":310,"repo_name":"myskill","origin_url":"https://github.com/zephyrwang6/myskill/blob/HEAD/markdown-to-image/SKILL.md","repo_owner":"zephyrwang6","body_sha256":"053f252d2e26c83d606a7b250487e24c2b966712d00474effa97707a0f0f9a8c","cluster_key":"9e33107ee10694a45e3a353e8033da71685f235852b92e42efc180617657f601","clean_bundle":{"format":"clean-skill-bundle-v1","source":"zephyrwang6/myskill/markdown-to-image/SKILL.md","attachments":[{"id":"f82b142d-24cd-5d5d-a5b7-ff4afb9f8578","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/f82b142d-24cd-5d5d-a5b7-ff4afb9f8578/attachment.py","path":"scripts/md2img.py","size":19590,"sha256":"31b31d85d54d76e1efbb64677cd4e09edda204158fd75d671843f265a3d554a0","contentType":"text/x-python; charset=utf-8"},{"id":"580b9640-cebe-5a04-8fa0-10031c9f18a7","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/580b9640-cebe-5a04-8fa0-10031c9f18a7/attachment.py","path":"scripts/md_to_image.py","size":24006,"sha256":"57b8008dd7743731f41b2a2384064900b2abcc1bfbdfa142bf29e485d4661b7d","contentType":"text/x-python; charset=utf-8"}],"bundle_sha256":"1ce15f6dbf76f15bb4b00913cfee8232529923ba7d2f1879ceb0b3c6369cbdd5","attachment_count":2,"text_attachments":2,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"markdown-to-image/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"media-content","category_label":"Media"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"media-content","import_tag":"clean-skills-v1","description":"将 Markdown 内容转换为精美的图片海报。特别适合将播客摘要、文章内容转为社交媒体分享图片。固定 3:4 比例,支持 YouTube 视频封面作为头图。触发词:「转图片」「Markdown 转图片」「生成海报」「生成分享图」「把这个转成图片」。"}},"renderedAt":1782980345569}

Markdown 转精美图片 将 Markdown 内容渲染为精美的分享海报图片,适合微信、小红书、微博等平台。 核心特性 - 固定 3:4 比例 (1080×1440 像素) - 自动分页 - 内容较多时生成多张图片 - 智能 SVG 头图 - 根据主题关键词自动生成相应风格的手绘线条图 - 智能标题 - 自动提取嘉宾名和主题,格式为「嘉宾:主题」 - 白色背景 + 大字体 - 清晰易读,专业排版 - 自适应布局 - 内容均匀分布,减少留白 - 宽字间距行间距 - 参考优秀海报排版 快速开始 基本用法 参数说明 | 参数 | 说明 | 默认值 | |------|------|--------| | , | Markdown 文件路径 | 必填 | | , | 输出目录 | | | , | 图片宽度(像素) | | | | 每页显示条目数 | | 输出规格 - 比例 : 固定 3:4(1080×1440 像素) - 格式 : PNG - 分页 : 自动根据内容生成多张图片 - 命名 : , , ... - 保存位置 : 默认 (MMDD 为当日日期) 智能 SVG 头图 根据文章主题自动生成不同风格的 SVG 装饰图: | 主题关键词 | 生成的 SVG 风格 | |-----------|----------------| | 、 、 | 神经网络节点 → 大脑 → 对话泡泡…