Skip to main content

crop-parsed-elements

Use when cropping figures, charts, tables, or other elements out of PDFs parsed with ai_parse_document (bbox coord), when extracting chart data from parsed documents or sending chart images to a vision model, or when crops come out misaligned or chart insights have wrong titles, units, or series names.

معلومات المصدر

المستودع
databricks-solutions/advance-document-processing
آخر نشاط في المصدر
٣ نوفمبر ٢٠٢٦ في ٠٥:١٤
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٢
التفرعات
٥

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
2 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
crop-parsed-elements
description
Use when cropping figures, charts, tables, or other elements out of PDFs parsed with ai_parse_document (bbox coord), when extracting chart data from parsed documents or sending chart images to a vision model, or when crops come out misaligned or chart insights have wrong titles, units, or series names.
# Cropping ai_parse_document Elements (and Getting Chart Data) ## Overview Two facts decide everything: **bbox coords are pixels of the page rendered at 200 DPI**, and **a crop alone loses the chart's title, units, and often its legend** — those are separate elements on the page. Without them a vision model invents the metric and drops the scale (observed: "Quarterly Revenue, $" for "Advertising Revenue by User Geography, In Millions"). For function syntax, use the `databricks-ai-functions` skill. ## First: do you need to crop at all? | Parse option `descriptionElementTypes` | Chart figure `content` | |---|---| | default `'*'` or includes `'figure'` | **Structured chart JSON** (series × categories, values exact on tested decks) + a prose `description` | | `''` | Raw label text only (`"$50,082\n$46,783…"`) | - Need chart data and can (re)parse with figures on → read figure `content` JSON (`builtin_chart_data`), add page context, done. No crop, no vision call. - Crop + vision model when: the corpus was parsed with `''` and re-parsing costs more than vision calls on figures only; you need your own schema or domain prompt; you need the image itself (review UI, OCR, audit); or built-in JSON is missing for a chart. - Either way, built-in JSON has `"title": "None"`, no units, and may name series `"Segment 1"` — always attach page context. ## Verified facts | | | |---|---| | `bbox[0].coord` | `[x0, y0, x1, y1]` int pixels, origin top-left, page rendered at **200 DPI** (px = PDF points × 200/72) | | Page image | Only with `imageOutputPath` (`pages[].image_uri`, same 200-DPI size); otherwise `null` | | Without page images | Render with `pypdfium2` at `scale=200/72` — aligns pixel-exact with the parser's image | | Page | `bbox[0].page_id` = 0-based PDF page index = `pages[].id` (not array position in chunked parses) | | Box tightness | Boxes touch content and move 2–3 px between parses — pad ~20 px | | Context | Title/units are `title` + short `text` above the chart; legends may be a `footnote` beside it | ## Implementation `scripts/crop_elements.py` (unit-tested). Install `pypdfium2` (Apache/BSD; PyMuPDF is AGPL), copy the file's contents **unchanged** into one cell, then: ```python %pip install pypdfium2 # own cell, first els = elements_to_crop(spark.table("<cat>.<sch>.<parsed_table>"), parsed_col="parsed", doc_id_col="path") display(els.select("doc_id", "page_id", "builtin_chart_json", "context")) # built-in data + context crops = crop_elements(spark, els, out_dir="/Volumes/<cat>/<sch>/<vol>/crops") # doc_id = source PDF path crops.write.mode("overwrite").saveAsTable("<cat>.<sch>.element_crops") # status: ok | too_small | bad_page | pdf_not_found | bad_pdf insights = vision_insights(spark, spark.table("<cat>.<sch>.element_crops"), "<vision endpoint>") ``` `vision_insights` calls `ai_query(endpoint, prompt + context, files => crop, failOnError => false)` (verified with Claude endpoints). With `failOnError => false` the result is a struct with fields **`result`** and **`errorMessage`** (verified live) — not `response` / `error`. To embed with document text, use `splice_figure_text(elements, {element_id: insight})` so each chart stays in reading order. `elements_to_crop(..., types=("table",))` crops tables too. ## Common mistakes | Mistake | Fix | |---|---| | Treating coords as PDF points, 72-DPI pixels, or 0–1 | 200-DPI pixels; scale by `render_dpi / 200` | | Calibrating coords from PDF text blocks | Fails on scanned pages; the scale is a constant | | Sending only the crop (or only a `caption`) | Pass same-page title, units, and adjacent legend (`figure_context`) | | Ignoring built-in figure `content` / `description` | Check it first; parse with figures on if chart data is the goal | | Parsing with `descriptionElementTypes: ''` then wanting chart data | That setting drops the chart JSON; re-parse or crop + vision | | Mapping page by array position | Use `bbox.page_id` | | No padding / no size floor | Pad ~20 px; skip tiny figures (logos) with `min_side_px` | | PyMuPDF in a customer project | AGPL — use `pypdfium2` | | Embedding vision text *and* running `ai_prep_search` on the original `parsed` | Built-in chart JSON gets embedded too; pick one representation per chart |
عرض على GitHub