All formats

MuPDF

LanguageC (C++, Java, Python, JavaScript and .NET bindings)
LicenseAGPL-3.0 or commercial license from Artifex
Repositorygithub.com/ArtifexSoftware/mupdf
Documentationmupdf.readthedocs.io
Depends onbundled third-party libraries (freetype, harfbuzz, zlib, libjpeg, gumbo and others)
Read / writeyes / no (.fb2)

MuPDF is a document rendering library (PDF, XPS, EPUB, MOBI, CBZ) with an HTML layout engine that also understands FictionBook 2. It maps FB2 elements (sections, titles, epigraphs, poems, notes) to styled blocks, shows the cover page from coverpage, decodes the Base64 binary images, and builds a table of contents from the section titles. After layout, an FB2 book works like a PDF: count pages, render, extract or search text, convert to PDF.

Use it to display FB2 or turn it into images or PDF. To read or change the FB2 XML itself, use an XML parser. MuPDF opens plain .fb2 files; unzip .fb2.zip / .fbz first. The AGPL license requires you to publish your source code if you distribute your program or offer it as a network service.

Installation#

Shell
# Debian / Ubuntu
sudo apt install libmupdf-dev
# Fedora
sudo dnf install mupdf-devel
# macOS
brew install mupdf
# Windows (vcpkg)
vcpkg install mupdf

Link with -lmupdf (static builds also need -lmupdf-third).

Basic usage: open an FB2 file and extract text#

C
#include <mupdf/fitz.h>
#include <stdio.h>

int main(int argc, char **argv) {
    if (argc < 2) {
        fprintf(stderr, "usage: %s book.fb2\n", argv[0]);
        return 1;
    }
    fz_context *ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
    if (!ctx) return 1;

    fz_document *doc = NULL;
    fz_buffer *buf = NULL;
    fz_var(doc);
    fz_var(buf);
    fz_try(ctx) {
        fz_register_document_handlers(ctx);
        doc = fz_open_document(ctx, argv[1]);
        fz_layout_document(ctx, doc, 420, 595, 11);  // A5 page in points, 11pt text

        char title[256];
        if (fz_lookup_metadata(ctx, doc, FZ_META_INFO_TITLE, title, sizeof title) > 0)
            printf("Title: %s\n", title);

        int n = fz_count_pages(ctx, doc);
        for (int i = 0; i < n; i++) {
            buf = fz_new_buffer_from_page_number(ctx, doc, i, NULL);
            fputs(fz_string_from_buffer(ctx, buf), stdout);
            fz_drop_buffer(ctx, buf);
            buf = NULL;
        }
    }
    fz_always(ctx) {
        fz_drop_buffer(ctx, buf);
        fz_drop_document(ctx, doc);
    }
    fz_catch(ctx) {
        fz_report_error(ctx);
        fz_drop_context(ctx);
        return 1;
    }
    fz_drop_context(ctx);
    return 0;
}

How to get the table of contents of an FB2 book#

C
static void print_outline(fz_context *ctx, fz_document *doc, fz_outline *o, int level) {
    for (; o; o = o->next) {
        int page = fz_page_number_from_location(ctx, doc, o->page);
        printf("%*s%s ... %d\n", level * 2, "", o->title ? o->title : "", page + 1);
        print_outline(ctx, doc, o->down, level + 1);
    }
}

fz_outline *outline = fz_load_outline(ctx, doc);  // after fz_layout_document
print_outline(ctx, doc, outline, 0);
fz_drop_outline(ctx, outline);

How to render the FB2 cover to PNG#

The first page shows the coverpage image:

C
fz_pixmap *pix = fz_new_pixmap_from_page_number(ctx, doc, 0, fz_scale(2, 2), fz_device_rgb(ctx), 0);
fz_save_pixmap_as_png(ctx, pix, "cover.png");
fz_drop_pixmap(ctx, pix);

How to convert FB2 to PDF#

C
fz_document_writer *wri = fz_new_document_writer(ctx, "book.pdf", "pdf", NULL);
int n = fz_count_pages(ctx, doc);
for (int i = 0; i < n; i++) {
    fz_page *page = fz_load_page(ctx, doc, i);
    fz_device *dev = fz_begin_page(ctx, wri, fz_bound_page(ctx, page));
    fz_run_page(ctx, page, dev, fz_identity, NULL);
    fz_end_page(ctx, wri);
    fz_drop_page(ctx, page);
}
fz_close_document_writer(ctx, wri);
fz_drop_document_writer(ctx, wri);

From the command line: mutool convert -o book.pdf book.fb2.

Tips#