// Rendering a page of a PDF document to a PNG image in less than 100 lines.12// Compile a debug build of mupdf, then compile and run this example:3//4// gcc -g -o build/debug/example -Iinclude docs/example.c \5// build/debug/libmupdf.a \6// build/debug/libfreetype.a build/debug/libjbig2dec.a \7// build/debug/libjpeg.a build/debug/libopenjpeg.a \8// build/debug/libmujs.a \9// build/debug/libz.a -lm10//11// build/debug/example /path/to/document.pdf 1 200 251213// Include the MuPDF header file.14#include <mupdf/fitz.h>1516void17render(char *filename, int pagenumber, int zoom, int rotation)18{19fz_context *ctx;20fz_document *doc;21int pagecount;22fz_page *page;23fz_matrix transform;24fz_rect bounds;25fz_irect bbox;26fz_pixmap *pix;27fz_device *dev;2829// Create a context to hold the exception stack and various caches.3031ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);3233// Register the default file types.3435fz_register_document_handlers(ctx);3637// Open the PDF, XPS or CBZ document.3839doc = fz_open_document(ctx, filename);4041// Retrieve the number of pages (not used in this example).4243pagecount = fz_count_pages(ctx, doc);4445// Load the page we want. Page numbering starts from zero.4647page = fz_load_page(ctx, doc, pagenumber - 1);4849// Calculate a transform to use when rendering. This transform50// contains the scale and rotation. Convert zoom percentage to a51// scaling factor. Without scaling the resolution is 72 dpi.5253fz_rotate(&transform, rotation);54fz_pre_scale(&transform, zoom / 100.0f, zoom / 100.0f);5556// Take the page bounds and transform them by the same matrix that57// we will use to render the page.5859fz_bound_page(ctx, page, &bounds);60fz_transform_rect(&bounds, &transform);6162// Create a blank pixmap to hold the result of rendering. The63// pixmap bounds used here are the same as the transformed page64// bounds, so it will contain the entire page. The page coordinate65// space has the origin at the top left corner and the x axis66// extends to the right and the y axis extends down.6768fz_round_rect(&bbox, &bounds);69pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb(ctx), &bbox);70fz_clear_pixmap_with_value(ctx, pix, 0xff);7172// A page consists of a series of objects (text, line art, images,73// gradients). These objects are passed to a device when the74// interpreter runs the page. There are several devices, used for75// different purposes:76//77// draw device -- renders objects to a target pixmap.78//79// text device -- extracts the text in reading order with styling80// information. This text can be used to provide text search.81//82// list device -- records the graphic objects in a list that can83// be played back through another device. This is useful if you84// need to run the same page through multiple devices, without85// the overhead of parsing the page each time.8687// Create a draw device with the pixmap as its target.88// Run the page with the transform.8990dev = fz_new_draw_device(ctx, pix);91fz_run_page(ctx, page, dev, &transform, NULL);92fz_drop_device(ctx, dev);9394// Save the pixmap to a file.9596fz_write_png(ctx, pix, "out.png", 0);9798// Clean up.99100fz_drop_pixmap(ctx, pix);101fz_drop_page(ctx, page);102fz_drop_document(ctx, doc);103fz_drop_context(ctx);104}105106int main(int argc, char **argv)107{108char *filename = argc >= 2 ? argv[1] : "";109int pagenumber = argc > 2 ? atoi(argv[2]) : 1;110int zoom = argc > 3 ? atoi(argv[3]) : 100;111int rotation = argc > 4 ? atoi(argv[4]) : 0;112113render(filename, pagenumber, zoom, rotation);114115return 0;116}117118119