Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7641 views
1
// Rendering a page of a PDF document to a PNG image in less than 100 lines.
2
3
// Compile a debug build of mupdf, then compile and run this example:
4
//
5
// gcc -g -o build/debug/example -Iinclude docs/example.c \
6
// build/debug/libmupdf.a \
7
// build/debug/libfreetype.a build/debug/libjbig2dec.a \
8
// build/debug/libjpeg.a build/debug/libopenjpeg.a \
9
// build/debug/libmujs.a \
10
// build/debug/libz.a -lm
11
//
12
// build/debug/example /path/to/document.pdf 1 200 25
13
14
// Include the MuPDF header file.
15
#include <mupdf/fitz.h>
16
17
void
18
render(char *filename, int pagenumber, int zoom, int rotation)
19
{
20
fz_context *ctx;
21
fz_document *doc;
22
int pagecount;
23
fz_page *page;
24
fz_matrix transform;
25
fz_rect bounds;
26
fz_irect bbox;
27
fz_pixmap *pix;
28
fz_device *dev;
29
30
// Create a context to hold the exception stack and various caches.
31
32
ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
33
34
// Register the default file types.
35
36
fz_register_document_handlers(ctx);
37
38
// Open the PDF, XPS or CBZ document.
39
40
doc = fz_open_document(ctx, filename);
41
42
// Retrieve the number of pages (not used in this example).
43
44
pagecount = fz_count_pages(ctx, doc);
45
46
// Load the page we want. Page numbering starts from zero.
47
48
page = fz_load_page(ctx, doc, pagenumber - 1);
49
50
// Calculate a transform to use when rendering. This transform
51
// contains the scale and rotation. Convert zoom percentage to a
52
// scaling factor. Without scaling the resolution is 72 dpi.
53
54
fz_rotate(&transform, rotation);
55
fz_pre_scale(&transform, zoom / 100.0f, zoom / 100.0f);
56
57
// Take the page bounds and transform them by the same matrix that
58
// we will use to render the page.
59
60
fz_bound_page(ctx, page, &bounds);
61
fz_transform_rect(&bounds, &transform);
62
63
// Create a blank pixmap to hold the result of rendering. The
64
// pixmap bounds used here are the same as the transformed page
65
// bounds, so it will contain the entire page. The page coordinate
66
// space has the origin at the top left corner and the x axis
67
// extends to the right and the y axis extends down.
68
69
fz_round_rect(&bbox, &bounds);
70
pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb(ctx), &bbox);
71
fz_clear_pixmap_with_value(ctx, pix, 0xff);
72
73
// A page consists of a series of objects (text, line art, images,
74
// gradients). These objects are passed to a device when the
75
// interpreter runs the page. There are several devices, used for
76
// different purposes:
77
//
78
// draw device -- renders objects to a target pixmap.
79
//
80
// text device -- extracts the text in reading order with styling
81
// information. This text can be used to provide text search.
82
//
83
// list device -- records the graphic objects in a list that can
84
// be played back through another device. This is useful if you
85
// need to run the same page through multiple devices, without
86
// the overhead of parsing the page each time.
87
88
// Create a draw device with the pixmap as its target.
89
// Run the page with the transform.
90
91
dev = fz_new_draw_device(ctx, pix);
92
fz_run_page(ctx, page, dev, &transform, NULL);
93
fz_drop_device(ctx, dev);
94
95
// Save the pixmap to a file.
96
97
fz_write_png(ctx, pix, "out.png", 0);
98
99
// Clean up.
100
101
fz_drop_pixmap(ctx, pix);
102
fz_drop_page(ctx, page);
103
fz_drop_document(ctx, doc);
104
fz_drop_context(ctx);
105
}
106
107
int main(int argc, char **argv)
108
{
109
char *filename = argc >= 2 ? argv[1] : "";
110
int pagenumber = argc > 2 ? atoi(argv[2]) : 1;
111
int zoom = argc > 3 ? atoi(argv[3]) : 100;
112
int rotation = argc > 4 ? atoi(argv[4]) : 0;
113
114
render(filename, pagenumber, zoom, rotation);
115
116
return 0;
117
}
118
119