Convert to PDF to PNG, JPG, BMP or TIFF - C++ Sample Code

Sample code to use Apryse SDK's built-in rasterizer to render PDF images on the fly and save the resulting images in various raster image formats (such as PNG, JPEG, BMP, TIFF). Samples provided in Python, C++, C#, Java, Node.js (JavaScript), PHP, Ruby, Go and VB. Learn more about our Server SDK and PDF Conversion Library.

1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6#include <PDF/PDFNet.h>
7#include <PDF/PDFDoc.h>
8#include <PDF/PDFDraw.h>
9#include <Filters/MappedFile.h>
10#include <Filters/FilterWriter.h>
11#include <cmath>
12#include <string>
13#include <iostream>
14#include <fstream>
15#include <sstream>
16#include <SDF/ObjSet.h>
17#include "../../LicenseKey/CPP/LicenseKey.h"
18
19using namespace std;
20using namespace pdftron;
21using namespace PDF;
22using namespace Filters;
23
24//---------------------------------------------------------------------------------------
25// The following sample illustrates how to convert PDF documents to various raster image
26// formats (such as PNG, JPEG, BMP, TIFF, etc), as well as how to convert a PDF page to
27// GDI+ Bitmap for further manipulation and/or display in WinForms applications.
28//---------------------------------------------------------------------------------------
29int main(int argc, char *argv[])
30{
31 try
32 {
33 // The first step in every application using PDFNet is to initialize the
34 // library and set the path to common PDF resources. The library is usually
35 // initialized only once, but calling Initialize() multiple times is also fine.
36 PDFNet::Initialize(LicenseKey);
37
38 // Optional: Set ICC color profiles to fine tune color conversion
39 // for PDF 'device' color spaces...
40
41 // PDFNet::SetResourcesPath("../../../resources");
42 // PDFNet::SetColorManagement(PDFNet::e_lcms);
43 // PDFNet::SetDefaultDeviceCMYKProfile("D:/Misc/ICC/USWebCoatedSWOP.icc");
44 // PDFNet::SetDefaultDeviceRGBProfile("AdobeRGB1998.icc"); // will search in PDFNet resource folder.
45
46 // ----------------------------------------------------
47 // Optional: Set predefined font mappings to override default font
48 // substitution for documents with missing fonts...
49
50 // PDFNet::AddFontSubst("StoneSans-Semibold", "C:/WINDOWS/Fonts/comic.ttf");
51 // PDFNet::AddFontSubst("StoneSans", "comic.ttf"); // search for 'comic.ttf' in PDFNet resource folder.
52 // PDFNet::AddFontSubst(PDFNet::e_Identity, "C:/WINDOWS/Fonts/arialuni.ttf");
53 // PDFNet::AddFontSubst(PDFNet::e_Japan1, "C:/Program Files/Adobe/Acrobat 7.0/Resource/CIDFont/KozMinProVI-Regular.otf");
54 // PDFNet::AddFontSubst(PDFNet::e_Japan2, "c:/myfonts/KozMinProVI-Regular.otf");
55 // PDFNet::AddFontSubst(PDFNet::e_Korea1, "AdobeMyungjoStd-Medium.otf");
56 // PDFNet::AddFontSubst(PDFNet::e_CNS1, "AdobeSongStd-Light.otf");
57 // PDFNet::AddFontSubst(PDFNet::e_GB1, "AdobeMingStd-Light.otf");
58
59 // Relative path to the folder containing test files.
60 string input_path = "../../TestFiles/";
61 string output_path = "../../TestFiles/Output/";
62
63 PDFDraw draw; // PDFDraw class is used to rasterize PDF pages.
64
65 //--------------------------------------------------------------------------------
66 // Example 1) Convert the first page to PNG and TIFF at 92 DPI.
67 // A three step tutorial to convert PDF page to an image.
68 try
69 {
70 // A) Open the PDF document.
71 PDFDoc doc((input_path + "tiger.pdf").c_str());
72
73 // Initialize the security handler, in case the PDF is encrypted.
74 doc.InitSecurityHandler();
75
76 // B) The output resolution is set to 92 DPI.
77 draw.SetDPI(92);
78
79 // C) Rasterize the first page in the document and save the result as PNG.
80 draw.Export(doc.GetPageIterator().Current(), (output_path + "tiger_92dpi.png").c_str());
81
82 cout << "Example 1: tiger_92dpi.png" << endl;
83
84 // Export the same page as TIFF
85 draw.Export(doc.GetPageIterator().Current(), (output_path + "tiger_92dpi.tif").c_str(), "TIFF");
86 }
87 catch(Common::Exception& e)
88 {
89 cout << e << endl;
90 }
91 catch(...)
92 {
93 cout << "Unknown Exception" << endl;
94 }
95
96 //--------------------------------------------------------------------------------
97 // Example 2) Convert the all pages in a given document to JPEG at 72 DPI.
98 cout << "Example 2:" << endl;
99 SDF::ObjSet hint_set; // A collection of rendering 'hits'.
100 try
101 {
102 PDFDoc doc((input_path + "newsletter.pdf").c_str());
103 // Initialize the security handler, in case the PDF is encrypted.
104 doc.InitSecurityHandler();
105
106 draw.SetDPI(72); // Set the output resolution is to 72 DPI.
107
108 // Use optional encoder parameter to specify JPEG quality.
109 SDF::Obj encoder_param=hint_set.CreateDict();
110 encoder_param.PutNumber("Quality", 80);
111
112 // Traverse all pages in the document.
113 for (PageIterator itr=doc.GetPageIterator(); itr.HasNext(); itr.Next()) {
114 ostringstream sstm;
115 sstm << output_path << "newsletter" << itr.Current().GetIndex() << ".jpg";
116 string path = sstm.str();
117 cout << "newsletter" << itr.Current().GetIndex() << ".jpg" << endl;
118
119 draw.Export(itr.Current(), path.c_str(), "JPEG", encoder_param);
120 }
121
122 cout << "Done." << endl;
123 }
124 catch(Common::Exception& e)
125 {
126 cout << e << endl;
127 }
128 catch(...)
129 {
130 cout << "Unknown Exception" << endl;
131 }
132
133
134 // Examples 3-6
135 try
136 {
137 // Common code for remaining samples.
138 PDFDoc tiger_doc((input_path + "tiger.pdf").c_str());
139 // Initialize the security handler, in case the PDF is encrypted.
140 tiger_doc.InitSecurityHandler();
141 Page page = tiger_doc.GetPage(1);
142
143 //--------------------------------------------------------------------------------
144 // Example 3) Convert the first page to raw bitmap. Also, rotate the
145 // page 90 degrees and save the result as RAW.
146 draw.SetDPI(100); // Set the output resolution is to 100 DPI.
147 draw.SetRotate(Page::e_90); // Rotate all pages 90 degrees clockwise.
148
149 int width = 0, height = 0, stride = 0;
150 double dpi = 0.0;
151 const UChar* buf = draw.GetBitmap(page, width, height, stride, dpi, PDFDraw::e_rgb);
152
153
154 // Save the raw RGB data to disk.
155 ofstream outfile((output_path + "tiger_100dpi_rot90.raw").c_str(), ofstream::binary);
156 outfile.write((char*)buf, height * stride);
157 outfile.close();
158
159
160 cout << "Example 3: tiger_100dpi_rot90.raw" << endl;
161 draw.SetRotate(Page::e_0); // Disable image rotation for remaining samples.
162
163 //--------------------------------------------------------------------------------
164 // Example 4) Convert PDF page to a fixed image size. Also illustrates some
165 // other features in PDFDraw class such as rotation, image stretching, exporting
166 // to grayscale, or monochrome.
167
168 // Initialize render 'gray_hint' parameter, that is used to control the
169 // rendering process. In this case we tell the rasterizer to export the image as
170 // 1 Bit Per Component (BPC) image.
171 SDF::Obj mono_hint=hint_set.CreateDict();
172 mono_hint.PutNumber("BPC", 1);
173
174 // SetImageSize can be used instead of SetDPI() to adjust page scaling
175 // dynamically so that given image fits into a buffer of given dimensions.
176 draw.SetImageSize(1000, 1000); // Set the output image to be 1000 wide and 1000 pixels tall
177 draw.Export(page, (output_path + "tiger_1000x1000.png").c_str(), "PNG", mono_hint);
178 cout << "Example 4: tiger_1000x1000.png" << endl;
179
180 draw.SetImageSize(200, 400); // Set the output image to be 200 wide and 300 pixels tall
181 draw.SetRotate(Page::e_180); // Rotate all pages 90 degrees clockwise.
182
183 // 'gray_hint' tells the rasterizer to export the image as grayscale.
184 SDF::Obj gray_hint=hint_set.CreateDict();
185 gray_hint.PutName("ColorSpace", "Gray");
186
187 draw.Export(page, (output_path + "tiger_200x400_rot180.png").c_str(), "PNG", gray_hint);
188 cout << "Example 4: tiger_200x400_rot180.png" << endl;
189
190 draw.SetImageSize(400, 200, false); // The third parameter sets 'preserve-aspect-ratio' to false.
191 draw.SetRotate(Page::e_0); // Disable image rotation.
192 draw.Export(page, (output_path + "tiger_400x200_stretch.jpg").c_str(), "JPEG");
193 cout << "Example 4: tiger_400x200_stretch.jpg" << endl;
194
195 //--------------------------------------------------------------------------------
196 // Example 5) Zoom into a specific region of the page and rasterize the
197 // area at 200 DPI and as a thumbnail (i.e. a 50x50 pixel image).
198 Rect zoom_rect(216, 522, 330, 600);
199 page.SetCropBox(zoom_rect); // Set the page crop box.
200
201 // Select the crop region to be used for drawing.
202 draw.SetPageBox(Page::e_crop);
203 draw.SetDPI(900); // Set the output image resolution to 900 DPI.
204 draw.Export(page, (output_path + "tiger_zoom_900dpi.png").c_str(), "PNG");
205 cout << "Example 5: tiger_zoom_900dpi.png" << endl;
206
207 // -------------------------------------------------------------------------------
208 // Example 6)
209 draw.SetImageSize(50, 50); // Set the thumbnail to be 50x50 pixel image.
210 draw.Export(page, (output_path + "tiger_zoom_50x50.png").c_str(), "PNG");
211 cout << "Example 6: tiger_zoom_50x50.png" << endl;
212 }
213 catch(Common::Exception& e)
214 {
215 cout << e << endl;
216 }
217 catch(...)
218 {
219 cout << "Unknown Exception" << endl;
220 }
221
222
223
224 //--------------------------------------------------------------------------------
225 // Example 7) Convert the first PDF page to CMYK TIFF at 92 DPI.
226 // A three step tutorial to convert PDF page to an image
227 try
228 {
229 pdftron::SDF::Obj cmyk_hint = hint_set.CreateDict();
230 cmyk_hint.PutName("ColorSpace", "CMYK");
231 // A) Open the PDF document.
232 PDFDoc doc((input_path + "tiger.pdf").c_str());
233 // Initialize the security handler, in case the PDF is encrypted.
234 doc.InitSecurityHandler();
235
236 // B) The output resolution is set to 92 DPI.
237 draw.SetDPI(92);
238
239 // C) Rasterize the first page in the document and save the result as TIFF.
240 Page pg = doc.GetPage(1);
241 draw.Export(pg, output_path + "out1.tif", "TIFF", cmyk_hint);
242 cout << "Example 7: out1.tif" << endl;
243 }
244 catch(Common::Exception& e)
245 {
246 cout << e << endl;
247 }
248 catch(...)
249 {
250 cout << "Unknown Exception" << endl;
251 }
252
253 //--------------------------------------------------------------------------------
254 // Example 8) PDFRasterizer can be used for more complex rendering tasks, such as
255 // strip by strip or tiled document rendering. In particular, it is useful for
256 // cases where you cannot simply modify the page crop box (interactive viewing,
257 // parallel rendering). This example shows how you can rasterize the south-west
258 // quadrant of a page.
259 try
260 {
261 // A) Open the PDF document.
262 PDFDoc doc((input_path + "tiger.pdf").c_str());
263 // Initialize the security handler, in case the PDF is encrypted.
264 doc.InitSecurityHandler();
265
266 // B) Get the page matrix
267 Page pg = doc.GetPage(1);
268 Page::Box box = Page::e_crop;
269 Common::Matrix2D mtx = pg.GetDefaultMatrix(true, box);
270 // We want to render a quadrant, so use half of width and height
271 const double pg_w = pg.GetPageWidth(box) / 2;
272 const double pg_h = pg.GetPageHeight(box) / 2;
273
274 // C) Scale matrix from PDF space to buffer space
275 const double dpi = 96.0;
276 const double scale = dpi / 72.0; // PDF space is 72 dpi
277 const int buf_w = static_cast<int>(floor(scale * pg_w));
278 const int buf_h = static_cast<int>(floor(scale * pg_h));
279 const int bytes_per_pixel = 4; // BGRA buffer
280 const int buf_size = buf_w * buf_h * bytes_per_pixel;
281 mtx.Translate(0, -pg_h); // translate by '-pg_h' since we want south-west quadrant
282 mtx = Common::Matrix2D(scale, 0, 0, scale, 0, 0) * mtx;
283
284 // D) Rasterize page into memory buffer, according to our parameters
285 std::vector<unsigned char> buf;
286 PDFRasterizer rast;
287 buf = rast.Rasterize(pg, buf_w, buf_h, buf_w * bytes_per_pixel, bytes_per_pixel, true, mtx);
288
289 // buf now contains raw BGRA bitmap.
290 cout << "Example 8: Successfully rasterized into memory buffer." << endl;
291 }
292 catch(Common::Exception& e)
293 {
294 cout << e << endl;
295 }
296 catch (...) {
297 cout << "Unknown Exception" << endl;
298 }
299 //--------------------------------------------------------------------------------
300 // Example 9) Export raster content to PNG using different image smoothing settings.
301 try
302 {
303 PDFDoc text_doc((input_path + "lorem_ipsum.pdf").c_str());
304 text_doc.InitSecurityHandler();
305
306 draw.SetImageSmoothing(false, false);
307 string filename = "raster_text_no_smoothing.png";
308 draw.Export(text_doc.GetPageIterator().Current(), (output_path + filename).c_str());
309 cout << "Example 9 a): " << filename << ". Done." << endl;
310
311 filename = "raster_text_smoothed.png";
312 draw.SetImageSmoothing(true, false /*default quality bilinear resampling*/);
313 draw.Export(text_doc.GetPageIterator().Current(), (output_path + filename).c_str());
314 cout << "Example 9 b): " << filename << ". Done." << endl;
315
316 filename = "raster_text_high_quality.png";
317 draw.SetImageSmoothing(true, true /*high quality area resampling*/);
318 draw.Export(text_doc.GetPageIterator().Current(), (output_path + filename).c_str());
319 cout << "Example 9 c): " << filename << ". Done." << endl;
320 }
321 catch(Common::Exception& e)
322 {
323 cout << e << endl;
324 }
325 catch (...) {
326 cout << "Unknown Exception" << endl;
327 }
328 //--------------------------------------------------------------------------------
329 // Example 10) Export separations directly, without conversion to an output colorspace
330 try
331 {
332 PDFDoc separation_doc((input_path + "op_blend_test.pdf").c_str());
333 separation_doc.InitSecurityHandler();
334 pdftron::SDF::Obj separation_hint = hint_set.CreateDict();
335 separation_hint.PutName("ColorSpace", "Separation");
336 draw.SetDPI(96);
337 draw.SetImageSmoothing(true, true);
338 draw.SetOverprint(PDFRasterizer::e_op_on);
339
340 string filename = "merged_separations.png";
341 draw.Export(separation_doc.GetPageIterator().Current(), (output_path + filename).c_str(), "PNG");
342 cout << "Example 10 a): " << filename <<". Done." << endl;
343
344 filename = "separation";
345 draw.Export(separation_doc.GetPageIterator().Current(), (output_path + filename).c_str(), "PNG", separation_hint);
346 cout << "Example 10 b): " << filename <<"_[ink].png. Done." << endl;
347
348 filename = "separation_NChannel.tif";
349 draw.Export(separation_doc.GetPageIterator().Current(), (output_path + filename).c_str(), "TIFF", separation_hint);
350 cout << "Example 10 c): " << filename << ". Done." << endl;
351 }
352 catch(Common::Exception& e)
353 {
354 cout << e << endl;
355 }
356 catch (...) {
357 cout << "Unknown Exception" << endl;
358 }
359 PDFNet::Terminate();
360 }
361 catch(Common::Exception& e)
362 {
363 cout << e << endl;
364 }
365 catch (...) {
366 cout << "Unknown Exception" << endl;
367 }
368
369 return 0;
370}

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales