This HTML page is not optimized for LLM or AI agent consumption. Fetch the Markdown version instead: /guides/python/editor/deskew-pdf-page.md — it contains the complete documentation content in clean, structured Markdown without any CSS, JavaScript, or navigation noise. Deskewing PDF pages | Nutrient Python SDK

Pages that come off a scanner or a phone camera are rarely square to the page. A few degrees of rotation is enough to hurt OCR accuracy, throw off barcode and table detection, and make an otherwise clean archive look sloppy. Deskewing straightens the page before any of that downstream work runs.

Deskewing at the page level keeps the operation narrow. You correct the pages you know came from a scanner and leave the rest of the document untouched, which matters in mixed documents where born-digital pages are already square.

This sample shows how to straighten a single page of a document using Nutrient Python SDK and save the result. The input can be any document format the SDK supports. If the input isn’t already a PDF, the SDK converts it to PDF automatically when you create the editor.

Download sample

How Nutrient helps

Nutrient Python SDK detects and corrects skew behind a single method call. The SDK:

  • Implicitly converts non-PDF inputs (images, multi-page TIFFs, Office documents) to PDF when the editor is created
  • Rasterizes the target page and measures its dominant text baseline angle
  • Rotates the page content by the detected angle to bring it back to square
  • Applies the correction to the page content stream, so text and vector art stay vector — the page isn’t flattened to an image
  • Leaves the page alone when no skew is detected

Other pages in the document aren’t touched.

Preparing the project

Import the classes used in the sample:

from nutrient_sdk import Document
from nutrient_sdk import PdfEditor
from nutrient_sdk import NutrientException

Opening the document

Open the source document and attach a PDF editor to it:

def main():
try:
with Document.open("input_skewed_scan.pdf") as document:
editor = PdfEditor.edit(document)

PdfEditor.edit(document) attaches an editor to the open document. If the input isn’t already a PDF, the SDK converts it to PDF at this step. The context manager(opens in a new tab) closes the document when the block exits, even if deskewing raises.

Tuning detection

Three document settings control the detector, and they must be set before you deskew.

skew_tolerance is the search window in degrees — skew larger than this isn’t corrected. Narrow it when you know your scans are only slightly off and you want to avoid over-correcting a page whose layout merely looks slanted.

optimistic_skew_detection relaxes the confidence checks that suppress a borderline result. Enable it when you already know a batch is skewed and the conservative pass is reporting nothing. Leave it off for mixed input, where it raises the chance of rotating a page that was actually straight.

skew_binarization_method chooses how the page is reduced to black and white before the skew is measured. Set it to "sauvola" for faint, grayish, or unevenly lit scans, where a global threshold loses too much text for the detector to lock onto. "default" and "otsu" both use Modified Otsu.

document.settings.deskew_settings.skew_tolerance = 10.0
document.settings.deskew_settings.optimistic_skew_detection = False
document.settings.deskew_settings.skew_binarization_method = "default"

All three have sensible defaults (a 15-degree window, conservative detection, Modified Otsu), so you can skip this step entirely and call auto_deskew() directly.

These settings are shared with the recognition pipelines, so the same values apply if you later run OCR or data extraction over the document. The other properties on DeskewSettings cover model-based cardinal orientation correction, which runs only in those pipelines and doesn’t affect a page-level deskew.

Straightening a single page

Get the target page from the editor and deskew it:

pages = editor.get_page_collection()
page = pages.get_first()
applied_angle = page.auto_deskew()
if applied_angle != 0:
print(f"Corrected a skew of {applied_angle:.2f} degrees.")
else:
print("No skew detected, page left unchanged.")

editor.get_page_collection().get_first() returns the first page of the document, and auto_deskew() measures that page’s skew and rotates its content to correct it. A page the detector reads as already square is left unchanged, so the call is safe to run over pages you aren’t sure about.

The return value is the rotation that was applied, in degrees, and is 0 when nothing was corrected. Use it to log what happened or to flag pages that came in badly skewed.

To target a different page, use the page collection accessor (for example pages.get(2) for the third page) and call auto_deskew() on that page instead.

Saving the result

Save the modified document to a new file and close the editor:

editor.save_as("output.pdf")
editor.close()
except NutrientException as e:
print(f"Error: {e}")
if __name__ == "__main__":
main()

The except clause surfaces any licensing or I/O issue raised by the SDK. Deskewing requires an unencrypted document — an encrypted source raises an error rather than silently skipping the page.

Conclusion

The workflow for deskewing a single PDF page is:

  1. Open the source document.
  2. Create a PdfEditor for the document.
  3. Optionally tune skew_tolerance and optimistic_skew_detection on the document settings.
  4. Get the target page from editor.get_page_collection().
  5. Call auto_deskew() on that page.
  6. Save the result and close the editor.

Only the targeted page is straightened. The rest of the document is left as it was.

For related workflows, refer to the Python SDK guides.