Overview
Use this script to extract and save each parsed chunk as a separate PNG. This is useful for building datasets, analyzing chunk quality, or processing individual document regions.These examples require the Python or TypeScript client library. Before running a script, set your API key and install the library and any required dependencies.
Scripts
from pathlib import Path
from datetime import datetime
from landingai_ade import LandingAIADE
from PIL import Image
import pymupdf
def save_chunks_as_images(parse_response, document_path, output_base_dir="groundings"):
"""Save each parsed chunk as a separate image file."""
# Create timestamped output directory
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
document_name = Path(document_path).stem
output_dir = Path(output_base_dir) / f"{document_name}_{timestamp}"
def save_page_chunks(image, chunks, page_num):
"""Save all chunks for a specific page."""
img_width, img_height = image.size
# Create page-specific directory
page_dir = output_dir / f"page_{page_num}"
page_dir.mkdir(parents=True, exist_ok=True)
for chunk in chunks:
# Check if chunk belongs to this page
if chunk.grounding.page != page_num:
continue
box = chunk.grounding.box
# Convert normalized coordinates to pixel coordinates
x1 = int(box.left * img_width)
y1 = int(box.top * img_height)
x2 = int(box.right * img_width)
y2 = int(box.bottom * img_height)
# Crop the chunk region
chunk_img = image.crop((x1, y1, x2, y2))
# Save with descriptive filename
filename = f"{chunk.type}.{chunk.id}.png"
output_path = page_dir / filename
chunk_img.save(output_path)
print(f"Saved chunk: {output_path}")
if document_path.suffix.lower() == '.pdf':
pdf = pymupdf.open(document_path)
total_pages = len(pdf)
for page_num in range(total_pages):
page = pdf[page_num]
pix = page.get_pixmap(matrix=pymupdf.Matrix(2, 2)) # 2x scaling for clarity
img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
# Save chunks for this page
save_page_chunks(img, parse_response.chunks, page_num)
pdf.close()
else:
# Load image file directly
img = Image.open(document_path)
if img.mode != "RGB":
img = img.convert("RGB")
# Save chunks for single page
save_page_chunks(img, parse_response.chunks, 0)
print(f"\nAll chunks saved to: {output_dir}")
return output_dir
# Initialize client (uses the API key from the VISION_AGENT_API_KEY environment variable)
client = LandingAIADE()
# Replace with your file path
document_path = Path("/path/to/file/document")
# Parse the document
print("Parsing document...")
parse_response = client.parse(
document=document_path,
model="dpt-2-latest"
)
print("Parsing complete!")
# Save chunks as images
save_chunks_as_images(parse_response, document_path)
import LandingAIADE from "landingai-ade";
import fs from "fs";
import path from "path";
import { createCanvas, loadImage } from "canvas";
import { pdf } from "pdf-to-img";
async function saveChunksAsImages(
parseResponse: any,
documentPath: string,
outputBaseDir: string = "groundings"
) {
// Create timestamped output directory
const timestamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, -5);
const documentName = path.basename(documentPath, path.extname(documentPath));
const outputDir = path.join(outputBaseDir, `${documentName}_${timestamp}`);
async function savePageChunks(
imageBuffer: Buffer,
chunks: any[],
pageNum: number
) {
// Load the page image
const image = await loadImage(imageBuffer);
const imgWidth = image.width;
const imgHeight = image.height;
// Create page-specific directory
const pageDir = path.join(outputDir, `page_${pageNum}`);
if (!fs.existsSync(pageDir)) {
fs.mkdirSync(pageDir, { recursive: true });
}
// Process each chunk
for (const chunk of chunks) {
// Check if chunk belongs to this page
if (chunk.grounding.page !== pageNum) {
continue;
}
const box = chunk.grounding.box;
// Convert normalized coordinates to pixel coordinates
const x1 = Math.floor(box.left * imgWidth);
const y1 = Math.floor(box.top * imgHeight);
const x2 = Math.floor(box.right * imgWidth);
const y2 = Math.floor(box.bottom * imgHeight);
// Calculate crop dimensions
const width = x2 - x1;
const height = y2 - y1;
// Create canvas for cropped chunk
const canvas = createCanvas(width, height);
const ctx = canvas.getContext("2d");
// Draw the cropped region
ctx.drawImage(image, x1, y1, width, height, 0, 0, width, height);
// Save with descriptive filename
const filename = `${chunk.type}.${chunk.id}.png`;
const outputPath = path.join(pageDir, filename);
const buffer = canvas.toBuffer("image/png");
fs.writeFileSync(outputPath, buffer);
console.log(`Saved chunk: ${outputPath}`);
}
}
const fileExtension = path.extname(documentPath).toLowerCase();
if (fileExtension === ".pdf") {
// Convert PDF to images
const document = await pdf(documentPath, { scale: 2.0 });
let pageNum = 0;
for await (const page of document) {
console.log(`Processing page ${pageNum}...`);
await savePageChunks(page, parseResponse.chunks, pageNum);
pageNum++;
}
} else {
// Load image file directly
const imageBuffer = fs.readFileSync(documentPath);
await savePageChunks(imageBuffer, parseResponse.chunks, 0);
}
console.log(`\nAll chunks saved to: ${outputDir}`);
return outputDir;
}
// Initialize client (uses the API key from the VISION_AGENT_API_KEY environment variable)
const client = new LandingAIADE();
async function extractChunks() {
// Replace with your file path
const documentPath = "/path/to/file/document";
// Parse the document
console.log("Parsing document...");
const parseResponse = await client.parse({
document: fs.createReadStream(documentPath),
model: "dpt-2-latest"
});
console.log("Parsing complete!");
// Save each chunk as a separate image
await saveChunksAsImages(parseResponse, documentPath);
}
extractChunks();
Directory Structure for Saved Images
Images are saved with this structure:groundings/
└── document_TIMESTAMP/
└── page_0/
└── ChunkType.CHUNK_ID.png
TIMESTAMPis the time and date the document was parsed (format:YYYYMMDD_HHMMSSfor Python, ISO format for TypeScript)page_0is the zero-indexed page numberChunkTypeis the chunk typeCHUNK_IDis the unique chunk identifier (UUID format)
groundings/
└── document_20250117_143022/
├── page_0/
│ ├── text.c5f81e1b-37d2-46bf-89e1-4983c1a36444.png
│ ├── table.a2b91c3d-48e5-4f67-9123-5678abcdef12.png
│ └── figure.e9f12345-6789-4abc-def0-123456789abc.png
└── page_1/
├── text.f1a23456-7890-4bcd-ef12-3456789abcde.png
└── marginalia.b3c45678-9012-4def-5678-90abcdef1234.png