All formats

Poppler

LanguageC++ (APIs: poppler-cpp, poppler-glib for C, poppler-qt5/qt6)
LicenseGPL-2.0-or-later or GPL-3.0 (parts originally from Xpdf)
Repositorygitlab.freedesktop.org/poppler/poppler
Documentationpoppler.freedesktop.org, poppler-cpp API
Depends onFreeType, fontconfig, zlib, libjpeg, libpng, libtiff, OpenJPEG, lcms2; Cairo for the GLib API
Read / writeyes / limited: render, extract text, fonts, attachments, forms; save metadata changes and form values

Poppler is a fork of Xpdf and the PDF engine behind GNOME Papers/Evince, Okular, LibreOffice’s PDF import, Inkscape and the poppler-utils command line tools (pdftotext, pdftoppm, pdfinfo, pdffonts, pdfimages, pdfunite, pdfseparate). It renders accurately (with Splash or Cairo backends) and extracts text with a good layout mode.

Use the poppler-cpp or poppler-glib API: the core classes (PDFDoc, GfxState) are internal and change between releases. Poppler is GPL, so a program that links it must be GPL-compatible. It isn’t meant for creating PDFs or for structural edits like merging (the command line tools do simple merges).

Installation#

Shell
# Debian / Ubuntu
sudo apt install libpoppler-cpp-dev poppler-utils
# Fedora
sudo dnf install poppler-cpp-devel poppler-utils
# macOS
brew install poppler
# Windows (vcpkg)
vcpkg install poppler

With CMake and pkg-config:

cmake
find_package(PkgConfig REQUIRED)
pkg_check_modules(POPPLER REQUIRED IMPORTED_TARGET poppler-cpp)
target_link_libraries(myapp PRIVATE PkgConfig::POPPLER)

Basic usage: extract text and render a page#

C++
#include <poppler-document.h>
#include <poppler-page.h>
#include <poppler-page-renderer.h>
#include <poppler-image.h>
#include <iostream>
#include <memory>

int main() {
    std::unique_ptr<poppler::document> doc(poppler::document::load_from_file("in.pdf"));
    if (!doc || doc->is_locked()) {
        std::cerr << "cannot open file\n";
        return 1;
    }
    std::cout << doc->pages() << " pages\n";

    for (int i = 0; i < doc->pages(); i++) {
        std::unique_ptr<poppler::page> page(doc->create_page(i));
        poppler::byte_array utf8 = page->text().to_utf8();
        std::cout << std::string(utf8.begin(), utf8.end()) << "\n";
    }

    // render page 1 at 150 dpi
    std::unique_ptr<poppler::page> first(doc->create_page(0));
    poppler::page_renderer renderer;
    renderer.set_render_hint(poppler::page_renderer::antialiasing, true);
    renderer.set_render_hint(poppler::page_renderer::text_antialiasing, true);
    poppler::image img = renderer.render_page(first.get(), 150, 150);
    if (!img.is_valid() || !img.save("page1.png", "png")) {
        std::cerr << "render failed\n";
        return 1;
    }
    return 0;
}

How to extract text with the physical layout#

page::text takes a rectangle (empty for the whole page) and a layout mode. physical_layout keeps columns and table cells in place, like pdftotext -layout:

C++
poppler::ustring text = page->text(poppler::rectf(), poppler::page::physical_layout);

page->text_list() returns text_box objects with each word’s bounding box.

How to read PDF metadata#

C++
auto to_utf8 = [](const poppler::ustring &s) {
    poppler::byte_array b = s.to_utf8();
    return std::string(b.begin(), b.end());
};
std::cout << "Title: " << to_utf8(doc->get_title()) << "\n";
std::cout << "Author: " << to_utf8(doc->get_author()) << "\n";
std::cout << "Producer: " << to_utf8(doc->get_producer()) << "\n";
int major, minor;
doc->get_pdf_version(&major, &minor);
std::cout << "PDF " << major << "." << minor
          << (doc->is_encrypted() ? ", encrypted" : "") << "\n";
// XMP metadata as XML
std::cout << to_utf8(doc->metadata()) << "\n";

How to open a password-protected PDF#

C++
std::unique_ptr<poppler::document> doc(
    poppler::document::load_from_file("secret.pdf", "owner-password", "user-password"));

Or call doc->unlock(owner, user) on a document where is_locked() returns true.

How to merge, split and convert with poppler-utils#

Shell
pdfunite a.pdf b.pdf merged.pdf          # merge
pdfseparate in.pdf page-%d.pdf           # split into single pages
pdftoppm -png -r 150 in.pdf page         # render every page to page-1.png, ...
pdftotext -layout in.pdf out.txt         # extract text keeping the layout
pdfinfo in.pdf                           # metadata, page size, encryption
pdfimages -all in.pdf img                # extract embedded images in their original format

Tips#