Server/Desktop PDF Content Extraction Library

The Apryse SDK offers deep, programmatic access to PDF content—so you can extract exactly what you need, fast.

Key capabilities include:

  • Text Extraction: Pull structured Unicode text with style, position, and layout details using pdftron.PDF.TextExtractor. Advanced options include ligature expansion, hidden/duplicated text handling, and more.
  • Signature Extraction: Retrieve digital signatures, timestamps, and verification details.
  • Graphics-Level Access: Extract and analyze graphical elements, including paths, color spaces, dash patterns, and transparency settings.
  • Low-Level Character Data: Access exact positioning of text runs and individual characters for precise downstream processing.
  • Font and Glyph Access: Extract embedded fonts and glyph outlines for advanced rendering or analysis.
  • Image Extraction: Extract all embedded images, with support for all PDF compression filters—including optional RAW output and color normalization.
  • Layer (OCG) Extraction: Programmatically access PDF layers and optional content groups.
  • Annotations and Forms: Retrieve all form fields, annotations, and widget data directly from the document.
  • Tagged PDF Support: Access marked content for tagged PDFs, enabling structure-aware extraction.
  • Embedded Objects: Extract ICC profiles, U3D streams, attachments, and embedded files.
  • Metadata Access: Read document metadata for title, author, keywords, and more.

Text Extraction

To extract text from a PDF document.

Text extraction reading ordering is not defined in the ISO PDF standard. In fact, there is no concept of sentence, paragraph, tables, or anything similar in a typical PDF file. This means each PDF vendor is left to their own design/solution and will extract text with some differences. Therefore, reading order is not guaranteed to match the order that a typical user reading the document would follow.

The reading order of a magazine, newspaper article, and an academic article are all quite different due to the lack of semantic information in a PDF and the placement/ordering of text in the document. Where different users may have different expectations of the correct reading order.

1PDFDoc doc = new PDFDoc(filename)
2Page page = doc.GetPage(1);
3
4TextExtractor txt = new TextExtractor();
5txt.Begin(page);
6
7// Extract words one by one.
8TextExtractor.Word word;
9for (TextExtractor.Line line = txt.GetFirstLine(); line.IsValid(); line=line.GetNextLine())
10{
11 for (word=line.GetFirstWord(); word.IsValid(); word=word.GetNextWord())
12 {
13 //word.GetString();
14 }
15}

Read a PDF File sample
Full sample code which illustrates the basic text extraction capabilities.

Extract text under an annotation

To extract text from under an annotation in the document.

1PDFDoc doc = new PDFDoc(filename)
2Page page = doc.GetPage(1);
3Annot annotation = page.GetAnnot(0);
4
5TextExtractor txt = new TextExtractor();
6txt.Begin(page); // Read the page.
7string textData = txt.GetTextUnderAnnot(annotation);

About extracting text

When we use the ElementReader class to read elements from a PDF document, we are often faced with data that is partial. For example, let us say that we are attempting to extract a sentence that says "This is a sample sentence." from a PDF document. We could potentially end up with two elements - "T" and "his is a sample sentence.". This is possible because in a PDF document, text objects are not always cleanly organized into words sentences, or paragraphs. The ElementReader class will return Element objects exactly as they are defined in the PDF page content stream.

Text runs

An element of type e_text directly corresponds to a Tj element in the PDF document. Each e_text element represents a text run, which represents a sequence of text glyphs that use the same font and graphics attributes. Say, if there is a single word, whose letters are each presented with a different font, then each letter would be a separate text run. You may also encounter text runs that contain multiple words separated by spaces. The PDF format does not guarantee that the text will be presented in reading order.

TextExtractor class

All this just goes to say that attempting to use an ElementReader to extract text data from a PDF document is not guaranteed to return data in the order expected (reading order). The most straightforward approach to extract words and text from text-runs is using the pdftron.PDF.TextExtractor class, as shown in the TextExtract sample project - TextExtract Sample

TextExtractor will assemble words, lines, and paragraphs, remove duplicate strings, reconstruct text reading order, etc. Using TextExtractor you can also obtain bounding boxes for each word, line, or paragraph (along with style information such as font, color, etc). This information can be used to search for corresponding text elements using ElementReader.

Image Extraction

To extract image content from a PDF document.

1PDFDoc doc = new PDFDoc(filename);
2ElementReader reader = new ElementReader();
3
4// Read page content on every page in the document
5for (PageIterator itr=doc.GetPageIterator(); itr.HasNext(); itr.Next())
6{
7 // Read the page
8 reader.Begin(itr.Current());
9 ProcessElements(reader);
10 reader.End();
11}
12
13void ProcessElements(ElementReader reader)
14{
15 Element element;
16
17 // Traverse the page display list
18 while ((element = reader.Next()) != null)
19 {
20 switch (element.GetType())
21 {
22 case Element.Type.e_image:
23 {
24 pdftron.PDF.Image image = new pdftron.PDF.Image(element.GetXObject());
25 image.Export(output_filename); // or ExporAsPng() or ExporAsTiff()
26 // optionally, you can also extract uncompressed/compressed
27 // image data directly using element.GetImageData()
28 }
29 break;
30 case Element.ElementType.e_form:
31 {
32 reader.FormBegin();
33 ProcessElements(reader);
34 reader.End();
35 break;
36 }
37 }
38 }
39}

PDF image extraction
Full code sample which illustrates a few approaches to PDF image extraction.

About reading page content

Page content is represented as a sequence of graphical Elements such as paths, text, images, and forms. The only effect of the ordering of Elements in the display list is the order in which Elements are painted. Elements that occur later in the display list can obscure earlier elements.

A display list can be traversed using an ElementReader object. To start traversing the display list, call reader.Begin(). Then, reader.Next() will return subsequent Elements until null is returned (marking the end of the display list).

While ElementReader only works with one page at a time, the same ElementReader object may be reused to process multiple pages.

About Form XObjects, Type3 font glyphs, and tiling patterns

A PDF page display list may contain child display lists of Form XObjects, Type3 font glyphs, and tiling patterns. A form XObject is a self-contained description of any sequence of graphics objects (such as path objects, text objects, and sampled images), defined as a PDF content stream. It may be painted multiple times — either on several pages or at several locations on the same page — and will produce the same results each time (subject only to the graphics state at the time the Form XObject is painted). In order to open a child display list for a Form XObject, call the reader.FormBegin() method. To return processing to the parent display list call reader.End(). Processing of the Form XObject display (traversing the child display list) is illustrated below.

Apryse Docs Image

Note that, in the above sample code, a child display list is opened when an element with type Element.ElementType.e_form is encountered by the reader.FormBegin() method. The child display list becomes the current display list until it is closed using reader.End(). At this point the processing is returned to the parent display list and the next Element returned will be the Element following the Form XObject. Also note that, because Form XObjects may be nested, a sub-display list could have its own child display lists. The sample above shows traversing these nested Form XObjects recursively.

Similarly, a pattern display list can be opened using reader.PatternBegin(), and a Type3 glyph display list can be opened using the reader.Type3FontBegin() method.

Embedded Form Extraction

To extract embedded fonts in a document.

1boolean ObjIsEmbeddedFont(Obj indirectObj) {
2 if (indirectObj.IsFree()) {
3 return false;
4 }
5
6 if (!indirectObj.IsDict() && !indirectObj.IsStream()) {
7 return false;
8 }
9
10 Obj typeObj = indirectObj.FindObj("Type");
11 if (typeObj == null || !typeObj.IsName()) {
12 return false;
13 }
14
15 var typeName = typeObj.GetName();
16 if (!typeName.Equals("Font")) {
17 return false;
18 }
19
20 Obj subtypeObj = indirectObj.FindObj("Subtype");
21 if (subtypeObj != null && subtypeObj.IsName()){
22 subtypeName = subtypeObj.GetName();
23 if (subtypeName.Equals("CIDFontType0")) {
24 return false;
25 }
26 }
27
28 Font font = new Font(indirectObj);
29 return font.IsEmbedded();
30}
31
32PDFDoc doc = new PDFDoc(filename)
33SDFDoc sdfdoc = doc.GetSDFDoc();
34for (int i = 1; i < sdfdoc.XRefSize(); ++i) {
35 Obj indirectObj = sdfdoc.GetObj(i);
36 if (ObjIsEmbeddedFont(indirectObj)) {
37 // perform document processing
38 }
39}

About embedded fonts

PDF documents access fonts from one of two places: the host machine rendering the PDF document or from within the PDF document itself. When a font is used in a PDF document which is not available on the machine loading that document and it's not embedded within the document the viewer will usually load a different font. When that font is contained within the PDF document itself we call that an embedded font. When a PDF contains an embedded font that font can still be rendered even if it is not defined on the host machine.

All font information in a PDF is stored in the SDF layer as an SDF object and exists as either a dictionary or a stream. When a font exists a dictionary that means that means that it is defined exclusively within the PDF document but if it is defined as a stream that means it exists as a file which may or may not exist within the PDF document itself. It is possible for either type to be embedded.

Apryse Docs Image

It's also possible to programatically embed fonts within a PDF with the Apryse SDK. You can find an example in the ElementBuilder sample code.

The samples below demonstrates how to iterate over all embedded fonts found within a PDF document. Note that because this requires several low-level operations additional care must be taken for to check for possible null pointers. Also note that fonts with the subtype CIDFontType0 are not not counted as embedded fonts because they are necessarily referenced by a parent font within the same document.

Get started

Extract text from a PDF
To extract text from a PDF document.

Extract embedded fonts from a PDF
To extract embedded fonts from a PDF document.

Tools & Utilities

PDF2Text
A utility for text extraction from PDF documents.

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales