PPT 視覺復刻

👤 allergro 📦 v1.4.1 ⭐ 4.4 ⬇️ 5.1K 下載
📄 辦公效率 免費

📖 技能介紹


name: ppt-vision-replica description: | 將PPT截圖或資訊圖轉換為可編輯的PPTX檔案。此技能基於Images2Slides論文(arXiv:2602.07645)實現, 利用視覺-語言模型(VLM)進行區域理解,通過座標對映演算法將畫素座標轉換為PPTX座標。 支援複雜形狀降級處理策略(custGeom/漸變/透明等無法直接還原的形狀轉為PNG嵌入)。 觸發場景:使用者上傳PPT截圖並要求復刻、使用者要求分析PPT結構、使用者希望將圖片PPT轉換為可編輯版本。 version: 1.5.0 requires: os: [linux, darwin, win32] npm: [pptxgenjs] python: [Pillow] # 僅複雜形狀降級時需要 filesystem: true # 讀寫臨時PNG和輸出PPTX檔案 network: true # 呼叫外部VLM處理影像(圖片資料會發送到配置的VLM服務端點)


⚠️ 使用前須知 - 圖片資料傳送:第一步 VLM 影像分析會將截圖傳送到配置的 VLM 服務端點(如 OpenClaw image 工具 / MiniMax Vision / GPT-4V 等)。請勿使用本技能處理涉密或敏感的幻燈片。 - 檔案系統:技能會生成臨時 PNG 檔案和輸出 PPTX 檔案,確保執行環境允許檔案讀寫操作。 - 執行時依賴:需提前安裝 npm install -g pptxgenjs;如需複雜形狀降級,還需安裝 Python + Pillow。

PPT視覺復刻技能 (v1.5)

將靜態PPT截圖/資訊圖轉換為可編輯PPTX檔案的完整工作流。

核心演算法 (Images2Slides論文適配)

座標對映 (Pixel → EMU)

EMU = Pixel × (914400 / DPI)
Slide_X = (Image_X / Image_Width) × Slide_Width_EMU
Slide_Y = (Image_Y / Image_Height) × Slide_Height_EMU

標準16:9幻燈片尺寸: 9144000 × 5143500 EMU

工作流程

階段1: 影像分析(開放式 VLM 呼叫)

第一步的圖片識別為開放式設計,可靈活接入任意具備影像理解能力的工具—— 如 OpenClaw 內建 image 工具(預設,MiniMax Vision VLM)、MCP VLM 服務、GPT-4V 等。 後續座標對映和 PPT 生成邏輯與具體 VLM 解耦,保持穩定。

必須使用以下增強版 Prompt,以確保符號精度和格式完整性:

const ENHANCED_PROMPT = `分析這張PPT截圖,精確輸出所有可見區域的資訊。

輸出格式為JSON陣列,每個元素包含:
{
  "id": "數字",
  "type": "rectangle | roundedRect | text | line | image",
  "role": "header_bar | title | subtitle | body | data_card | footer | decorator | bullet_list",
  "bounds": { "x": 畫素, "y": 畫素, "width": 畫素, "height": 畫素 },
  "color": "#十六進位制顏色(文字顏色或形狀填充色)",
  "backgroundColor": "#背景填充色(僅形狀適用)",
  "lineColor": "#邊框顏色(如有邊框)",
  "lineWidth": 邊框寬度,
  "content": "文字內容(保持原版的所有標點符號,全形/半形符號原樣保留)",
  "fontSize": 字號數字(磅),
  "fontFamily": "字型名稱",
  "fontWeight": "normal | bold",
  "align": "left | center | right",
  "lineSpacing": 行間距倍數(1.0/1.5/2.0),
  "charSpacing": 字元間距(磅),
  "bulletType": "無bullet則null,有bullet則填 ■ / ✓ / - 等符號",
  "cornerRadius": 圓角大小(僅roundedRect適用),
  "zIndex": 疊加層級(從0開始)
}

⚠️ 特別注意:
1. content 必須保持原版的所有標點符號,包括全形括號()和半形括號()的區別
2. 不要新增或刪除任何字元
3. 專案符號(■、✓、1.、-)必須原樣記錄在 bulletType 欄位
4. 識別所有行間距較大的文本框,填寫 lineSpacing
5. 邊框矩形必須填寫 lineColor,填充矩形填寫 backgroundColor
6. zIndex按照視覺層疊順序從後到前遞增`;

階段2: 結構化資料解析

呼叫 scripts/coordinate_mapper.js,支援4種JSON提取策略,自動容錯:

const { parseAnalysisToRegions, mapAllRegions } = require('./coordinate_mapper');

// 解析分析結果(自動處理全形符號校正和bullet識別)
const regions = parseAnalysisToRegions(analysisText);

// 批次對映座標
const mappedRegions = mapAllRegions(regions, imageWidth, imageHeight);

新增功能(v1.1): - normalizeSymbols(text) — 全形/半形符號校正 - detectBullet(text) — 識別並提取bullet符號型別 - 4策略JSON解析容錯(直接解析 → 陣列提取 → 物件提取 → 程式碼塊提取)

階段3: PPT生成

呼叫 scripts/ppt_generator.js

const { saveFromRegions } = require('./ppt_generator');

await saveFromRegions(mappedRegions, 'output.pptx', {
  imageWidth: 2100,
  imageHeight: 1192,
  background: '#FFFFFF'  // 可選背景色
});

區域型別對映

VLM輸出 PptxGenJS方法 v1.1新增支援
rectangle (filled) slide.addShape('rect') backgroundColor / lineColor
rectangle (border) slide.addShape('rect') lineWidth / dashType
roundedRect slide.addShape('roundRect') ✅ 新增 cornerRadius
text slide.addText() ✅ lineSpacing / charSpacing / bullet
line slide.addShape('line') dashType
image slide.addImage() data(base64) / path
複雜形狀 slide.addImage() + Python繪製PNG ✅ v1.2新增

複雜形狀降級處理策略 (v1.2)

核心思路:pptxgenjs 無法還原的複雜圖形,改用 Python/Pillow 繪製精確 PNG(透明背景)→ 嵌入 PPT 的方式替代。

何時觸發降級

遇到以下情況時,應將該形狀標記為 type: "complex_shape",使用降級策略處理:

形狀特徵 判斷依據
自定義多邊形路徑 XML中存在 <a:custGeom> 標籤,包含貝塞爾曲線、不規則路徑
透明漸變填充 多色漸變(3個以上 stop)或帶透明度通道(alpha < 100%)的漸變
複合漸變方向 漸變角度非水平/垂直(非0/90/180/270度),如斜向漸變
發光/陰影特效 <a:outerShdw>, <a:glow> 等複雜效果 pptxgenjs 渲染誤差大
不規則遮罩/裁切 圖片經過自定義路徑裁切(<p:spPr><a:custGeom> 包裹圖片)
VLM識別為漸變箭頭/裝飾圖形 從截圖分析中識別出型別為裝飾性漸變形狀

降級處理工作流

┌─────────────────────────────────────────────────────┐
│ 1. 判斷是否為複雜形狀(見上表)                          │
│    ├── 有原版PPTX → 從XML提取精確路徑和顏色引數            │
│    └── 僅截圖 → 用VLM估算形狀輪廓和漸變顏色                │
│                                                     │
│ 2. 用Python/Pillow繪製透明背景PNG                       │
│    ├── 繪製精確路徑(參考XML座標 或 VLM估算畫素)           │
│    ├── 應用漸變/透明/特效                               │
│    └── 輸出 RGBA 透明背景 PNG                          │
│                                                     │
│ 3. 嵌入PPT(addImage)                               │
│    └── 座標與原版對應(EMU換算或比例縮放)                  │
└─────────────────────────────────────────────────────┘

從原版XML提取形狀引數(有原始檔時優先)

當有原版 .pptx 可解包時,可獲取最精確的引數:

# 解包PPTX
unzip original.pptx -d pptx_unpacked/
# 檢視形狀XML
cat pptx_unpacked/ppt/slides/slide1.xml

關鍵欄位提取:

<!-- 自定義路徑形狀 -->
<a:custGeom>
  <a:pathLst>
    <a:path w="5725" h="1294">   <!-- 路徑畫布尺寸(EMU相對座標)-->
      <a:moveTo><a:pt x="2852" y="0"/></a:moveTo>  <!-- 起點 -->
      <a:cubicBezTo>...</a:cubicBezTo>              <!-- 貝塞爾曲線 -->
      <a:lnTo>...</a:lnTo>                          <!-- 直線段 -->
    </a:path>
  </a:pathLst>
</a:custGeom>

<!-- 漸變填充 -->
<a:gradFill>
  <a:gsLst>
    <a:gs pos="0"><a:srgbClr val="FFFFFF"/></a:gs>    <!-- 白色,pos=0% -->
    <a:gs pos="100000"><a:srgbClr val="C00000"/></a:gs> <!-- 紅色,pos=100% -->
  </a:gsLst>
  <a:lin ang="16200000" scaled="0"/>  <!-- ang=16200000 = 270°(EMU角度單位:60000/度)-->
</a:gradFill>

<!-- 形狀在組合(grpSp)中的位置 -->
<a:off x="696" y="2680"/>  <!-- 相對於組的偏移 -->
<a:ext cx="5725" cy="1294"/>  <!-- 形狀尺寸 -->

EMU角度轉換公式:

實際角度(度)= EMU角度值 / 60000
例: 16200000 / 60000 = 270°(即從上到下的漸變方向)

組合座標轉絕對座標公式:

// grp = { off: {x, y}, ext: {cx, cy}, chOff: {x, y}, chExt: {cx, cy} }
function absPos(grp, shape) {
  const scaleX = grp.ext.cx / grp.chExt.cx;
  const scaleY = grp.ext.cy / grp.chExt.cy;
  return {
    x: grp.off.x + (shape.x - grp.chOff.x) * scaleX,
    y: grp.off.y + (shape.y - grp.chOff.y) * scaleY,
    cx: shape.cx * scaleX,
    cy: shape.cy * scaleY,
  };
}

Python/Pillow 繪製複雜形狀 PNG(模板)

"""
複雜形狀PNG生成模板
適用於:自定義多邊形 + 漸變填充 + 透明背景
"""
from PIL import Image, ImageDraw
import numpy as np

# ========== 配置區 ==========
OUTPUT_PATH = "complex_shape.png"
# 畫布尺寸(可按EMU比例或螢幕畫素設定,建議寬度1000+)
CANVAS_W = 1200
CANVAS_H = 280

# 漸變顏色(從上到下,可擴充套件多個停止點)
GRADIENT_STOPS = [
    (0.0,   (255, 255, 255)),   # 白色 #FFFFFF
    (1.0,   (192,   0,   0)),   # 深紅 #C00000
]

# 形狀路徑點(歸一化座標 0~1,按原版路徑節點填寫)
# 說明:從XML的 custGeom 路徑座標除以路徑畫布寬高即可歸一化
SHAPE_POINTS_NORMALIZED = [
    (0.498, 0.0),   # 頂部尖角
    (1.0,   0.25),  # 右上
    (1.0,   1.0),   # 右下
    (0.0,   1.0),   # 左下
    (0.0,   0.25),  # 左上
]
# ========== 配置區結束 ==========

def lerp_color(c1, c2, t):
    return tuple(int(c1[i] + (c2[i] - c1[i]) * t) for i in range(3))

def gradient_color(y_ratio, stops):
    """根據y比例插值漸變顏色"""
    for i in range(len(stops) - 1):
        p0, c0 = stops[i]
        p1, c1 = stops[i + 1]
        if p0 <= y_ratio <= p1:
            t = (y_ratio - p0) / (p1 - p0)
            return lerp_color(c0, c1, t)
    return stops[-1][1]

# 建立透明畫布
img = Image.new("RGBA", (CANVAS_W, CANVAS_H), (0, 0, 0, 0))

# 構建蒙版(形狀區域)
mask = Image.new("L", (CANVAS_W, CANVAS_H), 0)
draw_mask = ImageDraw.Draw(mask)
pixel_points = [(int(x * CANVAS_W), int(y * CANVAS_H)) for x, y in SHAPE_POINTS_NORMALIZED]
draw_mask.polygon(pixel_points, fill=255)

# 逐行填充漸變色
pixels = img.load()
mask_pixels = mask.load()
for row in range(CANVAS_H):
    y_ratio = row / CANVAS_H
    color = gradient_color(y_ratio, GRADIENT_STOPS)
    for col in range(CANVAS_W):
        if mask_pixels[col, row] > 0:
            pixels[col, row] = (*color, mask_pixels[col, row])

img.save(OUTPUT_PATH)
print(f"已生成: {OUTPUT_PATH} ({CANVAS_W}x{CANVAS_H})")

貝塞爾曲線取樣(針對含 cubicBezTo 的複雜路徑):

完整實現已打包在 scripts/complex_shape.py,支援命令列直接呼叫: bash python scripts/complex_shape.py \ --output complex_shape.png \ --width 1200 --height 280 \ --gradient-stops "0.0:#FFFFFF,1.0:#C00000" \ --polygon "0.498,0.0 1.0,0.25 1.0,1.0 0.0,1.0 0.0,0.25"


嵌入PPT(addImage)

const PptxGenJS = require('pptxgenjs');

// EMU → 英寸(pptxgenjs座標單位為英寸)
const EMU_PER_INCH = 914400;
function emuToInch(emu) { return emu / EMU_PER_INCH; }

// 嵌入生成的PNG(座標來自absPos計算結果)
slide.addImage({
  path: './complex_shape.png',    // 或 data: base64String
  x: emuToInch(absPos.x),
  y: emuToInch(absPos.y),
  w: emuToInch(absPos.cx),
  h: emuToInch(absPos.cy),
});

僅有截圖時的降級策略

當沒有原版PPTX只有截圖時:

  1. 用VLM分析形狀:在分析Prompt中要求輸出形狀型別為 complex_shape,描述漸變顏色和方向
  2. 座標估算:從畫素座標按比例轉換為PPT EMU座標(精度約±5%)
  3. 顏色提取:要求VLM輸出漸變起止色的十六進位制值
  4. 形狀近似:若路徑複雜,可用多邊形近似(頂點數≥6通常足夠)

更新VLM分析Prompt中的type列舉,增加:

"type": "complex_shape",
"shapeDescription": "漸變方向/顏色/形狀型別的文字描述,供Python繪製參考",
"gradientStops": [{"pos": 0, "color": "#FFFFFF"}, {"pos": 1, "color": "#C00000"}],
"gradientAngle": 270

短期最佳化清單(v1.1已實現)

優先順序 問題 解決方案
P0 括號全形/半形差異 增強Prompt要求保留原版符號
P0 bullet符號丟失或錯誤 新增 detectBullet() + bulletType欄位
P0 行間距不一致 支援 lineSpacing 引數對映
P0 字元間距丟失 支援 charSpacing 引數對映
P1 JSON解析失敗 4策略容錯解析
P1 圓角矩形顯示為直角 新增 roundedRect 型別

快速執行命令

const { parseAnalysisToRegions, mapAllRegions } = require('./coordinate_mapper');
const { saveFromRegions } = require('./ppt_generator');

async function main(analysisResult, imageWidth, imageHeight, outputPath) {
  // 1. 解析區域(含符號校正)
  const regions = parseAnalysisToRegions(analysisResult);
  // 2. 座標對映
  const mapped = mapAllRegions(regions, imageWidth, imageHeight);
  // 3. 生成PPTX
  await saveFromRegions(mapped, outputPath, { imageWidth, imageHeight });
}

輸出規範

生成的PPTX必須包含: - 所有可見區域精確復刻 - 正確的疊加順序(zIndex) - 準確的顏色值 - 可編輯的文本內容(含正確的符號和行間距)

依賴

  • Node.js + pptxgenjs
  • 影像理解工具(開放式,預設 OpenClaw 內建 image 工具 / MiniMax Vision MCP)
  • coordinate_mapper.js(座標轉換 + 符號校正)
  • ppt_generator.js(PPT生成 + 格式支援)

方案B:基於原版PPTX的內容替換(ZIP直接操作法)

適用場景:使用者有原版 .pptx 檔案,只需替換文字內容,保留所有樣式、母版、配色、custGeom、媒體檔案。
優點:100%保留原版視覺效果,無需重建任何形狀,檔案結構完整可靠。
與方案A的選擇原則:有原版PPTX → 優先方案B;僅有截圖 → 方案A(從零生成)。


核心思路

PPTX 本質是一個 ZIP 壓縮包。直接用 Python zipfile 操作: - 只替換 ppt/slides/slide1.xml(幻燈片內容) - 完整保留其他所有檔案(母版/佈局/主題/媒體/標籤等)

原版PPTX (89個檔案)
  └── ppt/slides/slide1.xml  ← 只替換這一個檔案
  └── ppt/slideMasters/      ← 保留
  └── ppt/slideLayouts/      ← 保留
  └── ppt/theme/             ← 保留
  └── ppt/media/             ← 保留(圖片、SVG等)
  └── [Content_Types].xml    ← 保留
  └── ...所有其他檔案         ← 保留

⚠️ 關鍵注意事項

  1. 必須用完整原版PPTX為基礎,不能用手動解包再重新打包的目錄(極易缺失檔案)
  2. 中文文本被拆散在多個 <a:r> 標籤中,不能直接字串替換,需整段 <a:p> 替換
  3. XML中特殊字元必須轉義<&lt;>&gt;&&amp;
  4. 替換前先用 xmllint --nooutxml.etree.ElementTree 驗證XML有效性

完整替換指令碼模板

import zipfile, re, io

src = '/path/to/original.pptx'   # 原版完整PPTX
out = '/path/to/output.pptx'      # 輸出路徑

# 1. 讀取 slide1.xml
with zipfile.ZipFile(src, 'r') as z:
    xml = z.read('ppt/slides/slide1.xml').decode('utf-8')

# =============================================
# 2. 文本替換(兩種策略,按情況選用)
# =============================================

# --- 策略A:簡單單Run替換(文本完整在一個 <a:t> 標籤內)---
# 格式:(舊文本含尖括號定位符, 新文本含尖括號定位符)
simple_replacements = [
    ('>舊文本1<', '>新文本1<'),
    ('>舊文本2<', '>新文本2<'),
    # ⚠️ 如果新文本含 < 或 > 必須轉義:
    ('>舊文本3<', '>誤差&lt;1%<'),
]
for old, new in simple_replacements:
    xml = xml.replace(old, new)

# --- 策略B:整段替換(中文被拆散在多個 <a:r> 中時使用)---
def replace_para_containing(xml_str, search_text, new_text, rPr_override=None):
    """
    找到包含 search_text 的整個 <a:p> 段落,替換為只含 new_text 的新段落。
    保留原段落的 pPr(段落格式)和 rPr(文字格式)。
    """
    idx = xml_str.find(f'>{search_text}<')
    if idx < 0:
        print(f'⚠️  未找到文本:{search_text}')
        return xml_str
    start = xml_str.rfind('<a:p>', 0, idx)
    end = xml_str.find('</a:p>', idx) + 6
    old_para = xml_str[start:end]
    # 提取段落格式
    pPr_match = re.search(r'<a:pPr.*?</a:pPr>', old_para, re.DOTALL)
    pPr = pPr_match.group() if pPr_match else ''
    # 提取文字格式(優先自閉合 rPr)
    if rPr_override:
        rPr = rPr_override
    else:
        rPr_match = re.search(r'<a:rPr(?:\s[^>]*)*/>', old_para)
        if not rPr_match:
            rPr_match = re.search(r'<a:rPr.*?</a:rPr>', old_para, re.DOTALL)
        rPr = rPr_match.group() if rPr_match else '<a:rPr/>'
    new_para = f'<a:p>{pPr}<a:r>{rPr}<a:t>{new_text}</a:t></a:r></a:p>'
    return xml_str.replace(old_para, new_para, 1)

# 呼叫示例
xml = replace_para_containing(xml, '原始文本片段', '替換後的完整文本')
# 如果連 search_text 的定位符也找不到,說明文本被拆散更細,
# 此時需檢查XML原文,找到任意未被拆散的子串作為 search_text

# =============================================
# 3. 驗證XML有效性(替換後必做)
# =============================================
import xml.etree.ElementTree as ET
try:
    ET.fromstring(xml)
    print('✅ XML驗證通過')
except ET.ParseError as e:
    print(f'❌ XML解析錯誤:{e}')
    # 定位錯誤行列,檢查是否有未轉義的特殊字元

# =============================================
# 4. 打包輸出(保留原檔案所有內容)
# =============================================
buf = io.BytesIO()
with zipfile.ZipFile(src, 'r') as zin:
    with zipfile.ZipFile(buf, 'w', zipfile.ZIP_DEFLATED) as zout:
        for item in zin.infolist():
            if item.filename == 'ppt/slides/slide1.xml':
                zout.writestr(item, xml.encode('utf-8'))
            else:
                zout.writestr(item, zin.read(item.filename))

with open(out, 'wb') as f:
    f.write(buf.getvalue())
print(f'✅ 已生成:{out}')

除錯技巧

查詢文本在XML中的實際位置:

# 先解包檢視原始XML結構
with zipfile.ZipFile(src, 'r') as z:
    xml = z.read('ppt/slides/slide1.xml').decode('utf-8')

# 搜尋目標文本(注意:可能是片段,不是完整句子)
target = '要查詢的文本'
idx = xml.find(target)
if idx >= 0:
    print(xml[max(0, idx-200):idx+200])  # 列印前後200字元上下文
else:
    # 中文被拆散時,嘗試搜尋其中一個漢字或標點
    print('未找到完整文本,嘗試搜尋子串')

判斷應該用策略A還是B:

文本在XML中是連續的 <a:t>完整文本</a:t> → 用策略A(簡單替換)
文本被拆散為多個 <a:r>...<a:t>片</a:t></a:r><a:r>...<a:t>段</a:t></a:r> → 用策略B(整段替換)

常見錯誤與解決

錯誤 原因 解決
PowerPoint無法讀取檔案 打包基礎檔案不完整(缺media/theme等) 必須用原版完整PPTX為基礎,不能用手動解包目錄
XML解析報錯(column XXXX) 替換文本含未轉義的 < > & 轉義為 &lt; &gt; &amp;
替換未生效 中文文本被拆散在多個 <a:r> 改用 replace_para_containing() 整段替換
找不到 search_text 數字/標點與漢字分開在不同 run 搜尋純漢字或標點子串定位,再整段替換
slideMaster.xml.rels 為空 解包時內容丟失(此問題僅在手動解包時出現) 從原版PPTX直接操作,不會有此問題

變更日誌

v1.5.0 (2026-03-27)

  • 修復 ClawHub 審查問題:新增 requires metadata 宣告執行時依賴(npm:pptxgenjs, python:Pillow)
  • 新增完整指令碼scripts/complex_shape.py 提供可直接執行的複雜形狀 PNG 生成工具
  • 新增使用前須知:明確圖片資料傳送至外部 VLM 的隱私說明、檔案系統讀寫說明、執行時依賴

v1.4.0 (2026-03-26)

  • VLM 呼叫方式升級:移除 minimax-understand-image 技能依賴,改為開放式 VLM 呼叫設計,預設 OpenClaw 內建 image 工具
  • 適配 MiniMax 作為模型提供商時的內建 Vision 能力

v1.3.0 (2026-03-26)

  • 新增"方案B:基於原版PPTX的內容替換(ZIP直接操作法)"
  • 明確方案A(從零生成)vs 方案B(原版替換)的選擇原則
  • 提供完整的 Python zipfile 操作模板(只替換 slide1.xml,保留所有其他檔案)
  • 提供兩種替換策略:策略A(簡單單Run替換)+ 策略B(整段 <a:p> 替換)
  • 提供 replace_para_containing() 通用函式,解決中文文本被拆散在多個 <a:r> 的問題
  • 提供除錯技巧(XML上下文列印、策略A/B判斷方法)
  • 提供常見錯誤排查表(檔案損壞/XML解析報錯/替換未生效等)
  • 總結關鍵注意事項:必須用完整原版PPTX、特殊字元必須轉義等

v1.2.0 (2026-03-26)

  • 新增"複雜形狀降級處理策略"(核心功能升級)
  • 明確7類需要降級的形狀判斷標準(custGeom/透明漸變/斜向漸變/特效/裁切等)
  • 提供完整的 Python/Pillow 繪製模板(含多邊形 + 逐行漸變 + 透明背景)
  • 提供貝塞爾曲線取樣函式(適配 XML cubicBezTo

    來源於7w4.net。

  • 提供XML引數提取指南(路徑座標、漸變色、EMU角度轉換、組合座標變換)
  • 提供 addImage 嵌入程式碼模板
  • 補充僅有截圖時的降級策略(VLM估算 + 多邊形近似)
  • 區域型別對映表新增 complex_shape

v1.1.0 (2026-03-26)

  • 增強分析Prompt(短期最佳化P0方案)
  • 增加全形/半形符號校正 normalizeSymbols()
  • 增加bullet符號識別 detectBullet()
  • 增加行間距 lineSpacing 渲染支援
  • 增加字元間距 charSpacing 渲染支援
  • 增加圓角矩形 roundedRect 型別支援
  • 增加JSON解析4策略容錯
  • 改進多行文本段落渲染

v1.0.0 (2026-03-26)

  • 初始版本,基於Images2Slides論文實現基本復刻流程

🤖 AI 評測

這個技能能把 PPT 截圖轉換成可編輯的 PPTX 檔案,功能實用且技術文件非常詳細。不過實際使用時可能遇到版本號對不上的問題,而且文件缺少簡單直觀的完整操作示例,對於不熟悉技術細節的使用者來說,上手可能有一定門檻。總體質量中規中矩,理論基礎紮實,但配套的指引材料還可以更完善。

📊 多維度評分

適應性4.3
規範性4.2
有效性4.7
可靠性4
可信度4.8

📁 包含檔案 (6 個)

📄 SKILL.md 22.8 KB
📄 _meta.json 137 B
📄 references/region_schema.json 3.3 KB
📄 scripts/complex_shape.py 6.2 KB
📄 scripts/coordinate_mapper.js 5.9 KB
📄 scripts/ppt_generator.js 7.3 KB