Skip to content

Page Operations

PDF Oxide provides a complete set of page-level operations: rotation, media and crop box control, margin cropping, page merging, extraction, content erasure, and page reordering.

Binding coverage. Page-level operations are fully exposed in Python, Rust, and WASM. The Go binding covers rotation, delete/move page, EraseRegion, CropMargins, and MergeFrom on DocumentEditor. The C# DocumentEditor currently does not expose page-level operations — use the Rust CLI or call through Go/Python for page manipulation from a C# workflow.

Page Rotation

Get Rotation

Retrieve the current rotation of a page in degrees (0, 90, 180, or 270).

from pdf_oxide import PdfDocument

doc = PdfDocument("input.pdf")
rotation = doc.page_rotation(0)
print(f"Page 0 is rotated {rotation} degrees")
use pdf_oxide::editor::DocumentEditor;

let mut editor = DocumentEditor::open("input.pdf")?;
let rotation = editor.get_page_rotation(0)?;
println!("Page 0 is rotated {} degrees", rotation);
editor, _ := pdfoxide.OpenEditor("input.pdf")
defer editor.Close()

rotation, _ := editor.PageRotation(0)
fmt.Printf("Page 0 is rotated %d degrees\n", rotation)

Set Rotation

Set the absolute rotation for a specific page.

doc = PdfDocument("input.pdf")
doc.set_page_rotation(0, 90)   # Rotate page 0 to 90 degrees
doc.save("rotated.pdf")
import { WasmPdfDocument } from "pdf-oxide-wasm";

const doc = new WasmPdfDocument(bytes);
doc.setPageRotation(0, 90);
const output = doc.save();
doc.free();
let mut editor = DocumentEditor::open("input.pdf")?;
editor.set_page_rotation(0, 90)?;
editor.save("rotated.pdf")?;
editor, _ := pdfoxide.OpenEditor("input.pdf")
defer editor.Close()

_ = editor.SetPageRotation(0, 90)
_ = editor.Save("rotated.pdf")

Rotate By (Incremental)

Add a rotation increment to the existing rotation.

let mut editor = DocumentEditor::open("input.pdf")?;

// Rotate page 0 by an additional 90 degrees
editor.rotate_page_by(0, 90)?;

editor.save("rotated.pdf")?;

Rotate All Pages

Apply the same rotation to every page in the document.

doc = PdfDocument("input.pdf")
doc.rotate_all_pages(180)
doc.save("flipped.pdf")
import { WasmPdfDocument } from "pdf-oxide-wasm";

const doc = new WasmPdfDocument(bytes);
doc.rotateAllPages(180);
const output = doc.save();
doc.free();
let mut editor = DocumentEditor::open("input.pdf")?;
editor.rotate_all_pages(180)?;
editor.save("flipped.pdf")?;

Media Box and Crop Box

The MediaBox defines the full physical page size. The CropBox defines the visible region (the area displayed and printed).

Get and Set MediaBox

doc = PdfDocument("input.pdf")

# Get MediaBox: (llx, lly, urx, ury)
box = doc.page_media_box(0)
print(f"MediaBox: {box}")

# Set MediaBox to US Letter (612 x 792 points)
doc.set_page_media_box(0, 0, 0, 612, 792)
doc.save("output.pdf")
import { WasmPdfDocument } from "pdf-oxide-wasm";

const doc = new WasmPdfDocument(bytes);

// Get MediaBox: [llx, lly, urx, ury]
const mediaBox = doc.pageMediaBox(0);
console.log("MediaBox:", mediaBox);

// Set MediaBox to US Letter (612 x 792 points)
doc.setPageMediaBox(0, 0, 0, 612, 792);
const output = doc.save();
doc.free();
let mut editor = DocumentEditor::open("input.pdf")?;

// Get MediaBox as [llx, lly, urx, ury]
let media_box = editor.get_page_media_box(0)?;
println!("MediaBox: {:?}", media_box);

// Set MediaBox
editor.set_page_media_box(0, [0.0, 0.0, 612.0, 792.0])?;
editor.save("output.pdf")?;

Get and Set CropBox

doc = PdfDocument("input.pdf")

# Get CropBox (returns None if not set)
crop = doc.page_crop_box(0)
print(f"CropBox: {crop}")

# Set CropBox to crop a 1-inch border (72 points = 1 inch)
doc.set_page_crop_box(0, 72, 72, 540, 720)
doc.save("cropped.pdf")
import { WasmPdfDocument } from "pdf-oxide-wasm";

const doc = new WasmPdfDocument(bytes);

// Get CropBox (null if not set)
const cropBox = doc.pageCropBox(0);
console.log("CropBox:", cropBox);

// Set CropBox to crop a 1-inch border (72 points = 1 inch)
doc.setPageCropBox(0, 72, 72, 540, 720);
const output = doc.save();
doc.free();
let mut editor = DocumentEditor::open("input.pdf")?;

// Get CropBox (None if not explicitly set)
let crop_box = editor.get_page_crop_box(0)?;
println!("CropBox: {:?}", crop_box);

// Set CropBox
editor.set_page_crop_box(0, [72.0, 72.0, 540.0, 720.0])?;
editor.save("cropped.pdf")?;

Crop Margins

A convenience method that sets the CropBox to be inset from the MediaBox by the specified margins on all pages.

doc = PdfDocument("input.pdf")

# Crop 0.5 inch (36pt) from all sides on every page
doc.crop_margins(36, 36, 36, 36)
doc.save("cropped.pdf")
import { WasmPdfDocument } from "pdf-oxide-wasm";

const doc = new WasmPdfDocument(bytes);

// Arguments: left, right, top, bottom (in points)
doc.cropMargins(36, 36, 36, 36);
const output = doc.save();
doc.free();
let mut editor = DocumentEditor::open("input.pdf")?;

// Arguments: left, right, top, bottom (in points)
editor.crop_margins(36.0, 36.0, 36.0, 36.0)?;
editor.save("cropped.pdf")?;
editor, _ := pdfoxide.OpenEditor("input.pdf")
defer editor.Close()

_ = editor.CropMargins(36, 36, 36, 36) // left, right, top, bottom
_ = editor.Save("cropped.pdf")

Merging PDFs

Merge All Pages from Another PDF

Append all pages from another PDF to the end of the current document.

use pdf_oxide::editor::DocumentEditor;

let mut editor = DocumentEditor::open("main.pdf")?;
let pages_added = editor.merge_from("appendix.pdf")?;
println!("Added {} pages", pages_added);
editor.save("combined.pdf")?;
editor, _ := pdfoxide.OpenEditor("main.pdf")
defer editor.Close()

added, _ := editor.MergeFrom("appendix.pdf")
fmt.Printf("Added %d pages\n", added)
_ = editor.Save("combined.pdf")

Merge Specific Pages

Select specific pages from the source PDF to append.

let mut editor = DocumentEditor::open("main.pdf")?;

// Merge only pages 0, 2, and 4 from the source
editor.merge_pages_from("source.pdf", &[0, 2, 4])?;
editor.save("selected.pdf")?;

Extracting Pages

Extract a subset of pages into a new PDF file.

from pdf_oxide import PdfDocument

doc = PdfDocument("document.pdf")

# Extract specific pages to a new file
doc.extract_pages([0, 2, 4], "selected_pages.pdf")
const doc = new WasmPdfDocument(bytes);

// Extract pages to new PDF
const extracted = doc.extractPages([0, 2, 4]);
// extracted is Uint8Array of new PDF

doc.free();
use pdf_oxide::editor::DocumentEditor;

let mut editor = DocumentEditor::open("book.pdf")?;

// Extract pages 0-4 (first 5 pages) to a new file
editor.extract_pages(&[0, 1, 2, 3, 4], "chapter1.pdf")?;

Content Erasure

Erase (whiteout) rectangular regions on a page. This draws a white rectangle over the specified area, visually hiding the content beneath.

Erase a Single Region

doc = PdfDocument("input.pdf")

# Erase a region: (page, llx, lly, urx, ury)
doc.erase_region(0, 72, 700, 300, 792)
doc.save("erased.pdf")
import { WasmPdfDocument } from "pdf-oxide-wasm";

const doc = new WasmPdfDocument(bytes);

// Erase a region: (pageIndex, llx, lly, urx, ury)
doc.eraseRegion(0, 72, 700, 300, 792);
const output = doc.save();
doc.free();
let mut editor = DocumentEditor::open("input.pdf")?;
editor.erase_region(0, [72.0, 700.0, 300.0, 792.0])?;
editor.save("erased.pdf")?;
editor, _ := pdfoxide.OpenEditor("input.pdf")
defer editor.Close()

// Arguments: pageIndex, x, y, width, height (in points)
_ = editor.EraseRegion(0, 72, 700, 228, 92)
_ = editor.Save("erased.pdf")

Erase Multiple Regions

doc = PdfDocument("input.pdf")
doc.erase_regions(0, [
    (72, 700, 300, 792),
    (72, 600, 300, 650),
])
doc.save("erased.pdf")
import { WasmPdfDocument } from "pdf-oxide-wasm";

const doc = new WasmPdfDocument(bytes);

// Pass regions as a flat Float32Array: [llx, lly, urx, ury, ...]
const regions = new Float32Array([
  72, 700, 300, 792,
  72, 600, 300, 650,
]);
doc.eraseRegions(0, regions);
const output = doc.save();
doc.free();
let mut editor = DocumentEditor::open("input.pdf")?;
editor.erase_regions(0, &[
    [72.0, 700.0, 300.0, 792.0],
    [72.0, 600.0, 300.0, 650.0],
])?;
editor.save("erased.pdf")?;

Clear Pending Erasures

Remove all pending erase operations for a page before saving.

doc.clear_erase_regions(0)
editor.clear_erase_regions(0);

Page Reordering and Manipulation

The EditableDocument trait provides page manipulation methods.

Remove a Page

doc = PdfDocument("document.pdf")
doc.delete_page(3)
doc.save("modified.pdf")
const doc = new WasmPdfDocument(bytes);
doc.deletePage(3);
const saved = doc.save();
doc.free();
use pdf_oxide::editor::{DocumentEditor, EditableDocument};

let mut editor = DocumentEditor::open("input.pdf")?;
editor.remove_page(2)?;  // Remove page at index 2
editor.save("output.pdf")?;
editor, _ := pdfoxide.OpenEditor("input.pdf")
defer editor.Close()

_ = editor.DeletePage(2) // Remove page at index 2
_ = editor.Save("output.pdf")

Move a Page

doc = PdfDocument("document.pdf")
doc.move_page(5, 1)  # Move page from position 5 to position 1
doc.save("reordered.pdf")
let mut editor = DocumentEditor::open("input.pdf")?;
editor.move_page(0, 3)?;  // Move page 0 to position 3
editor.save("reordered.pdf")?;
editor, _ := pdfoxide.OpenEditor("input.pdf")
defer editor.Close()

_ = editor.MovePage(0, 3) // Move page 0 to position 3
_ = editor.Save("reordered.pdf")

Duplicate a Page

let mut editor = DocumentEditor::open("input.pdf")?;
let new_index = editor.duplicate_page(0)?;  // Duplicate page 0
println!("Duplicate is at index {}", new_index);
editor.save("output.pdf")?;

Full API Reference

Rotation

Method Returns Description
get_page_rotation(index) Result<i32> Get rotation in degrees
set_page_rotation(index, degrees) Result<()> Set absolute rotation
rotate_page_by(index, degrees) Result<()> Add incremental rotation
rotate_all_pages(degrees) Result<()> Rotate every page

Page Boxes

Method Returns Description
get_page_media_box(index) Result<[f32; 4]> Get MediaBox
set_page_media_box(index, box) Result<()> Set MediaBox
get_page_crop_box(index) Result<Option<[f32; 4]>> Get CropBox
set_page_crop_box(index, box) Result<()> Set CropBox
crop_margins(left, right, top, bottom) Result<()> Crop all pages by margins

Merging and Extracting

Method Returns Description
merge_from(path) Result<usize> Merge all pages from another PDF
merge_pages_from(path, pages) Result<usize> Merge specific pages
extract_pages(pages, output) Result<()> Extract pages to new file

Content Erasure

Method Returns Description
erase_region(page, rect) Result<()> Erase one region
erase_regions(page, rects) Result<()> Erase multiple regions
clear_erase_regions(page) () Clear pending erasures

Page Management (EditableDocument)

Method Returns Description
page_count() Result<usize> Number of pages
get_page_info(index) Result<PageInfo> Page dimensions and rotation
remove_page(index) Result<()> Remove a page
move_page(from, to) Result<()> Reorder a page
duplicate_page(index) Result<usize> Duplicate a page

Advanced Example: Normalize Scanned Pages

use pdf_oxide::editor::{DocumentEditor, EditableDocument};

let mut editor = DocumentEditor::open("scanned.pdf")?;
let count = editor.current_page_count();

for i in 0..count {
    // Set all pages to portrait Letter size
    editor.set_page_media_box(i, [0.0, 0.0, 612.0, 792.0])?;

    // Reset any rotation
    editor.set_page_rotation(i, 0)?;

    // Apply uniform margins
    editor.set_page_crop_box(i, [36.0, 36.0, 576.0, 756.0])?;
}

editor.save("normalized.pdf")?;