or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

attachments.mdcli-tools.mddocument-management.mdimage-bitmap.mdindex.mdpage-manipulation.mdpage-objects.mdtext-processing.mdtransformation.mdversion-info.md

page-objects.mddocs/

0

# Page Objects and Graphics

1

2

Manipulation of PDF page objects including images, text, and vector graphics. Supports object transformation, insertion, removal, and detailed analysis of page content structure.

3

4

## Capabilities

5

6

### Page Object Base Class

7

8

The PdfObject class serves as the base for all page objects including text, images, and vector graphics.

9

10

```python { .api }

11

class PdfObject:

12

def get_pos(self) -> tuple:

13

"""

14

Get object position bounds.

15

16

Returns:

17

tuple: (left, bottom, right, top) bounding rectangle in PDF units

18

"""

19

20

def get_matrix(self) -> PdfMatrix:

21

"""

22

Get object transformation matrix.

23

24

Returns:

25

PdfMatrix: Current transformation matrix

26

"""

27

28

def set_matrix(self, matrix: PdfMatrix):

29

"""

30

Set object transformation matrix.

31

32

Parameters:

33

- matrix: PdfMatrix, new transformation matrix

34

"""

35

36

def transform(self, matrix: PdfMatrix):

37

"""

38

Apply transformation matrix to object.

39

40

Parameters:

41

- matrix: PdfMatrix, transformation to apply

42

"""

43

```

44

45

Basic object manipulation:

46

47

```python

48

import pypdfium2 as pdfium

49

50

pdf = pdfium.PdfDocument("document.pdf")

51

page = pdf[0]

52

53

# Iterate through page objects

54

for i in range(page.count_objects()):

55

obj = page.get_object(i)

56

57

# Get object information

58

bounds = obj.get_pos()

59

matrix = obj.get_matrix()

60

61

print(f"Object {i}:")

62

print(f" Type: {obj.type}")

63

print(f" Bounds: {bounds}")

64

print(f" Matrix: {matrix.get()}")

65

print(f" Level: {obj.level}")

66

```

67

68

### Page Object Properties

69

70

Access object metadata and relationships.

71

72

```python { .api }

73

@property

74

def raw(self) -> FPDF_PAGEOBJECT:

75

"""Raw PDFium page object handle."""

76

77

@property

78

def type(self) -> int:

79

"""Object type constant (text, image, path, etc.)."""

80

81

@property

82

def page(self) -> PdfPage:

83

"""Parent page containing this object."""

84

85

@property

86

def pdf(self) -> PdfDocument:

87

"""Parent document containing this object."""

88

89

@property

90

def level(self) -> int:

91

"""Nesting level of the object."""

92

```

93

94

### Image Objects

95

96

The PdfImage class provides specialized handling for image objects within PDF pages.

97

98

```python { .api }

99

class PdfImage(PdfObject):

100

@classmethod

101

def new(cls, pdf: PdfDocument) -> PdfImage:

102

"""

103

Create new image object.

104

105

Parameters:

106

- pdf: PdfDocument, parent document

107

108

Returns:

109

PdfImage: New image object (not yet inserted into page)

110

"""

111

112

def get_metadata(self) -> ImageInfo:

113

"""

114

Get image metadata information.

115

116

Returns:

117

ImageInfo: Named tuple with image format, mode, and filter information

118

"""

119

120

def get_size(self) -> tuple[int, int]:

121

"""

122

Get image dimensions.

123

124

Returns:

125

tuple: (width, height) in pixels

126

"""

127

128

def get_filters(self, skip_simple=False) -> list:

129

"""

130

Get list of filters applied to image data.

131

132

Parameters:

133

- skip_simple: bool, skip simple/common filters

134

135

Returns:

136

list: Filter names applied to image

137

"""

138

```

139

140

Image metadata structure:

141

142

```python { .api }

143

class ImageInfo(NamedTuple):

144

format: str # Image format (JPEG, PNG, etc.)

145

mode: str # Color mode (RGB, RGBA, L, etc.)

146

metadata: dict # Additional metadata

147

all_filters: list # All filters applied

148

complex_filters: list # Complex/uncommon filters

149

```

150

151

### Image Data Access

152

153

Extract and manipulate image data from PDF image objects.

154

155

```python { .api }

156

def get_bitmap(self, render=False) -> PdfBitmap:

157

"""

158

Get image as bitmap.

159

160

Parameters:

161

- render: bool, render image through PDFium (may change appearance)

162

163

Returns:

164

PdfBitmap: Image data as bitmap object

165

"""

166

167

def get_data(self, decode_simple=False) -> bytes:

168

"""

169

Get raw image data.

170

171

Parameters:

172

- decode_simple: bool, decode simple filters (like FlateDecode)

173

174

Returns:

175

bytes: Raw image data (may be compressed)

176

"""

177

178

def extract(self, dest: str, *args, **kwargs):

179

"""

180

Extract image to file.

181

182

Parameters:

183

- dest: str, output file path

184

- Additional parameters for format-specific options

185

186

Automatically detects image format and saves appropriately.

187

"""

188

```

189

190

Image processing examples:

191

192

```python

193

pdf = pdfium.PdfDocument("document.pdf")

194

page = pdf[0]

195

196

# Find and process all images on page

197

for i in range(page.count_objects()):

198

obj = page.get_object(i)

199

200

if isinstance(obj, pdfium.PdfImage):

201

print(f"\nProcessing image {i}:")

202

203

# Get image metadata

204

metadata = obj.get_metadata()

205

print(f" Format: {metadata.format}")

206

print(f" Mode: {metadata.mode}")

207

print(f" Size: {obj.get_size()}")

208

print(f" Filters: {metadata.all_filters}")

209

210

# Extract image to file

211

output_path = f"extracted_image_{i}.png"

212

try:

213

obj.extract(output_path)

214

print(f" Extracted to: {output_path}")

215

except Exception as e:

216

print(f" Extraction failed: {e}")

217

218

# Try getting as bitmap instead

219

try:

220

bitmap = obj.get_bitmap()

221

pil_image = bitmap.to_pil()

222

pil_image.save(output_path)

223

print(f" Converted and saved to: {output_path}")

224

except Exception as e2:

225

print(f" Bitmap conversion failed: {e2}")

226

227

# Analyze image position and transformation

228

bounds = obj.get_pos()

229

matrix = obj.get_matrix()

230

print(f" Position: {bounds}")

231

print(f" Transform: {matrix.get()}")

232

```

233

234

### Image Modification

235

236

Modify existing images or create new image objects.

237

238

```python { .api }

239

def load_jpeg(self, source, pages=None, inline=False, autoclose=True):

240

"""

241

Load JPEG data into image object.

242

243

Parameters:

244

- source: file path, bytes, or file-like object containing JPEG data

245

- pages: list of pages to apply to (None = current page)

246

- inline: bool, embed as inline image

247

- autoclose: bool, close source if file-like object

248

"""

249

250

def set_bitmap(self, bitmap: PdfBitmap, pages=None):

251

"""

252

Set image data from bitmap.

253

254

Parameters:

255

- bitmap: PdfBitmap, source bitmap data

256

- pages: list of pages to apply to (None = current page)

257

"""

258

```

259

260

Creating and modifying images:

261

262

```python

263

pdf = pdfium.PdfDocument.new()

264

page = pdf.new_page(612, 792) # US Letter

265

266

# Create new image object

267

img_obj = pdfium.PdfImage.new(pdf)

268

269

# Load JPEG data

270

img_obj.load_jpeg("photo.jpg")

271

272

# Position the image on page

273

transform = pdfium.PdfMatrix()

274

transform = transform.translate(100, 400) # Position

275

transform = transform.scale(200, 150) # Size

276

277

img_obj.set_matrix(transform)

278

279

# Insert into page

280

page.insert_object(img_obj)

281

282

# Generate content stream

283

page.gen_content()

284

285

# Save document

286

pdf.save("document_with_image.pdf")

287

```

288

289

### Object Transformation

290

291

Apply geometric transformations to page objects including rotation, scaling, and translation.

292

293

```python

294

def transform_objects_example(page):

295

"""Example of transforming page objects."""

296

297

for i in range(page.count_objects()):

298

obj = page.get_object(i)

299

300

if isinstance(obj, pdfium.PdfImage):

301

# Get current transformation

302

current_matrix = obj.get_matrix()

303

print(f"Current matrix: {current_matrix.get()}")

304

305

# Create new transformation

306

new_matrix = pdfium.PdfMatrix()

307

308

# Scale image to 150% size

309

new_matrix = new_matrix.scale(1.5, 1.5)

310

311

# Rotate 15 degrees

312

new_matrix = new_matrix.rotate(15)

313

314

# Move to new position

315

new_matrix = new_matrix.translate(50, 100)

316

317

# Combine with existing transformation

318

combined_matrix = current_matrix.multiply(new_matrix)

319

320

# Apply transformation

321

obj.set_matrix(combined_matrix)

322

323

print(f"New matrix: {combined_matrix.get()}")

324

325

# Usage

326

pdf = pdfium.PdfDocument("document.pdf")

327

page = pdf[0]

328

transform_objects_example(page)

329

330

# Regenerate content stream after transformations

331

page.gen_content()

332

pdf.save("transformed_document.pdf")

333

```

334

335

### Object Analysis

336

337

Analyze page objects for content extraction and document understanding.

338

339

```python

340

def analyze_page_objects(page):

341

"""Comprehensive page object analysis."""

342

343

analysis = {

344

'total_objects': page.count_objects(),

345

'images': [],

346

'text_objects': 0,

347

'path_objects': 0,

348

'other_objects': 0,

349

'coverage_area': 0

350

}

351

352

page_width, page_height = page.get_size()

353

page_area = page_width * page_height

354

355

for i in range(page.count_objects()):

356

obj = page.get_object(i)

357

bounds = obj.get_pos()

358

359

# Calculate object area

360

if bounds:

361

left, bottom, right, top = bounds

362

obj_area = (right - left) * (top - bottom)

363

analysis['coverage_area'] += obj_area

364

365

# Categorize objects

366

if isinstance(obj, pdfium.PdfImage):

367

img_info = {

368

'index': i,

369

'size': obj.get_size(),

370

'bounds': bounds,

371

'metadata': obj.get_metadata()._asdict()

372

}

373

analysis['images'].append(img_info)

374

375

elif obj.type == pdfium.raw.FPDF_PAGEOBJ_TEXT:

376

analysis['text_objects'] += 1

377

378

elif obj.type == pdfium.raw.FPDF_PAGEOBJ_PATH:

379

analysis['path_objects'] += 1

380

381

else:

382

analysis['other_objects'] += 1

383

384

# Calculate coverage percentage

385

analysis['coverage_percentage'] = (analysis['coverage_area'] / page_area) * 100

386

387

return analysis

388

389

# Usage

390

pdf = pdfium.PdfDocument("document.pdf")

391

392

for i, page in enumerate(pdf):

393

print(f"\n--- Page {i+1} Object Analysis ---")

394

analysis = analyze_page_objects(page)

395

396

print(f"Total objects: {analysis['total_objects']}")

397

print(f"Images: {len(analysis['images'])}")

398

print(f"Text objects: {analysis['text_objects']}")

399

print(f"Path objects: {analysis['path_objects']}")

400

print(f"Other objects: {analysis['other_objects']}")

401

print(f"Coverage: {analysis['coverage_percentage']:.1f}%")

402

403

# Detail image information

404

for img_info in analysis['images']:

405

print(f" Image {img_info['index']}: {img_info['size']} pixels")

406

print(f" Format: {img_info['metadata']['format']}")

407

print(f" Bounds: {img_info['bounds']}")

408

```

409

410

### Form XObjects

411

412

Handle PDF Form XObjects for reusable content and complex graphics. Form XObjects are reusable page content that can be embedded multiple times within documents.

413

414

```python { .api }

415

class PdfXObject:

416

"""

417

XObject helper class for managing reusable PDF content.

418

419

Form XObjects are self-contained graphic objects that can be referenced

420

multiple times within a PDF document. They're useful for templates,

421

logos, headers, footers, and other repeated content.

422

423

Attributes:

424

- raw: FPDF_XOBJECT, underlying PDFium XObject handle

425

- pdf: PdfDocument, reference to document this XObject belongs to

426

"""

427

428

def __init__(self, raw, pdf):

429

"""

430

Initialize XObject wrapper.

431

432

Parameters:

433

- raw: FPDF_XOBJECT, PDFium XObject handle

434

- pdf: PdfDocument, parent document

435

436

Note: XObjects are typically created via PdfDocument.page_as_xobject()

437

rather than direct instantiation.

438

"""

439

440

def as_pageobject(self) -> PdfObject:

441

"""

442

Convert Form XObject to independent page object.

443

444

Returns:

445

PdfObject: Page object representation of the XObject content

446

447

Creates an independent page object from the XObject that can be

448

inserted into pages. Multiple page objects can share the same

449

XObject resources. Page objects remain valid after XObject closure.

450

"""

451

452

def close(self):

453

"""Close and release XObject resources."""

454

```

455

456

Creating and using XObjects:

457

458

```python

459

import pypdfium2 as pdfium

460

461

# Load source document

462

source_pdf = pdfium.PdfDocument("source_document.pdf")

463

target_pdf = pdfium.PdfDocument.new()

464

465

# Convert a page to XObject for reuse

466

page_xobject = source_pdf.page_as_xobject(0, target_pdf)

467

468

# Create target page

469

target_page = target_pdf.new_page(612, 792)

470

471

# Create multiple page objects from the same XObject

472

header_obj = page_xobject.as_pageobject()

473

footer_obj = page_xobject.as_pageobject()

474

475

# Position header at top of page

476

header_matrix = pdfium.PdfMatrix()

477

header_matrix = header_matrix.translate(50, 700)

478

header_matrix = header_matrix.scale(0.5, 0.5) # Scale down

479

header_obj.set_matrix(header_matrix)

480

481

# Position footer at bottom

482

footer_matrix = pdfium.PdfMatrix()

483

footer_matrix = footer_matrix.translate(50, 50)

484

footer_matrix = footer_matrix.scale(0.3, 0.3) # Scale down more

485

footer_obj.set_matrix(footer_matrix)

486

487

# Insert both objects into page

488

target_page.insert_obj(header_obj)

489

target_page.insert_obj(footer_obj)

490

491

# Generate content and save

492

target_page.gen_content()

493

target_pdf.save("document_with_reused_content.pdf")

494

495

# XObject can be closed after page objects are created

496

page_xobject.close()

497

```

498

499

XObject reuse patterns:

500

501

```python

502

def create_template_document():

503

"""Create document with repeated template content."""

504

505

# Source document with logo/header content

506

logo_pdf = pdfium.PdfDocument("company_logo.pdf")

507

main_pdf = pdfium.PdfDocument.new()

508

509

# Convert logo page to reusable XObject

510

logo_xobject = logo_pdf.page_as_xobject(0, main_pdf)

511

512

# Create multiple pages with logo

513

for i in range(5):

514

page = main_pdf.new_page(612, 792)

515

516

# Add logo to each page

517

logo_obj = logo_xobject.as_pageobject()

518

519

# Position logo in top-right corner

520

logo_matrix = pdfium.PdfMatrix()

521

logo_matrix = logo_matrix.translate(450, 720) # Top-right

522

logo_matrix = logo_matrix.scale(0.2, 0.2) # Small size

523

logo_obj.set_matrix(logo_matrix)

524

525

page.insert_obj(logo_obj)

526

527

# Add page-specific content here

528

# ... (text, images, etc.)

529

530

page.gen_content()

531

532

# Clean up

533

logo_xobject.close()

534

logo_pdf.close()

535

536

return main_pdf

537

538

# Usage

539

template_doc = create_template_document()

540

template_doc.save("template_document.pdf")

541

template_doc.close()

542

```

543

544

### Exception Handling

545

546

Handle errors that may occur during image extraction and processing.

547

548

```python { .api }

549

class ImageNotExtractableError(Exception):

550

"""

551

Raised when image cannot be extracted from PDF.

552

553

This may occur due to:

554

- Unsupported image formats

555

- Corrupted image data

556

- Complex filter combinations

557

- Encrypted or protected images

558

"""

559

```

560

561

Safe image extraction:

562

563

```python

564

def safe_extract_images(page, output_dir):

565

"""Safely extract all images from page."""

566

import os

567

568

extracted_count = 0

569

failed_count = 0

570

571

for i in range(page.count_objects()):

572

obj = page.get_object(i)

573

574

if isinstance(obj, pdfium.PdfImage):

575

try:

576

# Try direct extraction first

577

output_path = os.path.join(output_dir, f"image_{i}.png")

578

obj.extract(output_path)

579

extracted_count += 1

580

print(f"Extracted image {i}")

581

582

except pdfium.ImageNotExtractableError:

583

# Try bitmap conversion

584

try:

585

bitmap = obj.get_bitmap(render=True)

586

pil_image = bitmap.to_pil()

587

output_path = os.path.join(output_dir, f"image_{i}_rendered.png")

588

pil_image.save(output_path)

589

extracted_count += 1

590

print(f"Rendered and extracted image {i}")

591

592

except Exception as e:

593

failed_count += 1

594

print(f"Failed to extract image {i}: {e}")

595

596

except Exception as e:

597

failed_count += 1

598

print(f"Unexpected error extracting image {i}: {e}")

599

600

return extracted_count, failed_count

601

602

# Usage

603

import os

604

os.makedirs("extracted_images", exist_ok=True)

605

606

pdf = pdfium.PdfDocument("document.pdf")

607

page = pdf[0]

608

609

extracted, failed = safe_extract_images(page, "extracted_images")

610

print(f"Successfully extracted: {extracted}")

611

print(f"Failed extractions: {failed}")

612

```

613

614

## Object Type Constants

615

616

Common object type constants available through the raw module:

617

618

```python

619

# Available through pypdfium2.raw

620

FPDF_PAGEOBJ_UNKNOWN = 0 # Unknown object type

621

FPDF_PAGEOBJ_TEXT = 1 # Text object

622

FPDF_PAGEOBJ_PATH = 2 # Path/vector graphics

623

FPDF_PAGEOBJ_IMAGE = 3 # Image object

624

FPDF_PAGEOBJ_SHADING = 4 # Shading object

625

FPDF_PAGEOBJ_FORM = 5 # Form XObject

626

```

627

628

Object type identification:

629

630

```python

631

for i in range(page.count_objects()):

632

obj = page.get_object(i)

633

634

type_names = {

635

pdfium.raw.FPDF_PAGEOBJ_TEXT: "Text",

636

pdfium.raw.FPDF_PAGEOBJ_PATH: "Path",

637

pdfium.raw.FPDF_PAGEOBJ_IMAGE: "Image",

638

pdfium.raw.FPDF_PAGEOBJ_SHADING: "Shading",

639

pdfium.raw.FPDF_PAGEOBJ_FORM: "Form"

640

}

641

642

type_name = type_names.get(obj.type, "Unknown")

643

print(f"Object {i}: {type_name} (type {obj.type})")

644

```