PDFDraw

Sample Obj-C 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). Learn more about our iOS 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#import <OBJC/PDFNetOBJC.h>
7#import <Foundation/Foundation.h>
8#include <math.h>
9#include <stdio.h>
10
11//---------------------------------------------------------------------------------------
12// The following sample illustrates how to convert PDF documents to various raster image
13// formats (such as PNG, JPEG, BMP, TIFF, etc), as well as how to convert a PDF page to
14// GDI+ Bitmap for further manipulation and/or display in WinForms applications.
15//---------------------------------------------------------------------------------------
16int main(int argc, char *argv[])
17{
18 @autoreleasepool {
19 @try
20 {
21 // The first step in every application using PDFNet is to initialize the
22 // library and set the path to common PDF resources. The library is usually
23 // initialized only once, but calling Initialize() multiple times is also fine.
24 [PTPDFNet Initialize: 0];
25
26 // Optional: Set ICC color profiles to fine tune color conversion
27 // for PDF 'device' color spaces...
28
29 // PDFNet::SetResourcesPath("../../../resources");
30 // PDFNet::SetColorManagement();
31 // PDFNet::SetDefaultDeviceCMYKProfile("D:/Misc/ICC/USWebCoatedSWOP.icc");
32 // PDFNet::SetDefaultDeviceRGBProfile("AdobeRGB1998.icc"); // will search in PDFNet resource folder.
33
34 // ----------------------------------------------------
35 // Optional: Set predefined font mappings to override default font
36 // substitution for documents with missing fonts...
37
38 // PDFNet::AddFontSubst("StoneSans-Semibold", "C:/WINDOWS/Fonts/comic.ttf");
39 // PDFNet::AddFontSubst("StoneSans", "comic.ttf"); // search for 'comic.ttf' in PDFNet resource folder.
40 // PDFNet::AddFontSubst(PDFNet::e_Identity, "C:/WINDOWS/Fonts/arialuni.ttf");
41 // PDFNet::AddFontSubst(PDFNet::e_Japan1, "C:/Program Files/Adobe/Acrobat 7.0/Resource/CIDFont/KozMinProVI-Regular.otf");
42 // PDFNet::AddFontSubst(PDFNet::e_Japan2, "c:/myfonts/KozMinProVI-Regular.otf");
43 // PDFNet::AddFontSubst(PDFNet::e_Korea1, "AdobeMyungjoStd-Medium.otf");
44 // PDFNet::AddFontSubst(PDFNet::e_CNS1, "AdobeSongStd-Light.otf");
45 // PDFNet::AddFontSubst(PDFNet::e_GB1, "AdobeMingStd-Light.otf");
46
47 PTPDFDraw *draw = [[PTPDFDraw alloc] initWithDpi: 92]; // PDFDraw class is used to rasterize PDF pages.
48
49 //--------------------------------------------------------------------------------
50 // Example 1) Convert the first page to PNG and TIFF at 92 DPI.
51 // A three step tutorial to convert PDF page to an image.
52 @try
53 {
54 // A) Open the PDF document.
55 PTPDFDoc *doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/tiger.pdf"];
56
57 // Initialize the security handler, in case the PDF is encrypted.
58 [doc InitSecurityHandler];
59
60 // B) The output resolution is set to 92 DPI.
61 [draw SetDPI: 92];
62
63 // C) Rasterize the first page in the document and save the result as PNG.
64 [draw Export:[doc GetPage: 1] filename: @"../../TestFiles/Output/tiger_92dpi.png" format: @"PNG"];
65
66 NSLog(@"Example 1: tiger_92dpi.png");
67
68 // Export the same page as TIFF
69 [draw Export:[doc GetPage: 1] filename: @"../../TestFiles/Output/tiger_92dpi.tif" format: @"TIFF"];
70 }
71 @catch(NSException *e)
72 {
73 NSLog(@"%@", e.reason);
74 }
75
76 //--------------------------------------------------------------------------------
77 // Example 2) Convert the all pages in a given document to JPEG at 72 DPI.
78 NSLog(@"Example 2:");
79 PTObjSet *hint_set = [[PTObjSet alloc] init]; // A collection of rendering 'hits'.
80 @try
81 {
82 PTPDFDoc *doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/newsletter.pdf"];
83 // Initialize the security handler, in case the PDF is encrypted.
84 [doc InitSecurityHandler];
85
86 [draw SetDPI: 72]; // Set the output resolution is to 72 DPI.
87
88 // Use optional encoder parameter to specify JPEG quality.
89 PTObj *encoder_param=[hint_set CreateDict];
90 [encoder_param PutNumber: @"Quality" value: 80];
91
92 // Traverse all pages in the document.
93 PTPageIterator *itr;
94 for (itr=[doc GetPageIterator: 1]; [itr HasNext]; [itr Next]) {
95 NSString *filename = [NSString stringWithFormat: @"newsletter%d.jpg", [[itr Current] GetIndex]];
96 NSLog(@"%@", filename);
97 NSString *filenameWithPath = [@"../../TestFiles/Output/" stringByAppendingPathComponent: filename];
98
99 [draw ExportWithObj: [itr Current] filename: filenameWithPath format: @"JPEG" encoder_params: encoder_param];
100 }
101
102 NSLog(@"Done.");
103 }
104 @catch(NSException *e)
105 {
106 NSLog(@"%@", e.reason);
107 }
108
109 // Examples 3-5
110 @try
111 {
112 // Common code for remaining samples.
113 PTPDFDoc *tiger_doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/tiger.pdf"];
114 // Initialize the security handler, in case the PDF is encrypted.
115 [tiger_doc InitSecurityHandler];
116 PTPage *page = [tiger_doc GetPage: 1];
117
118 //--------------------------------------------------------------------------------
119 // Example 3) Convert the first page to raw bitmap. Also, rotate the
120 // page 90 degrees and save the result as RAW.
121 [draw SetDPI: 100]; // Set the output resolution is to 100 DPI.
122 [draw SetRotate: e_pt90]; // Rotate all pages 90 degrees clockwise.
123
124 PTBitmapInfo* buf = [draw GetBitmap: page pix_fmt: e_ptrgb demult: NO];
125
126 // Save the raw RGB data to disk.
127 [[buf GetBuffer] writeToFile: @"../../TestFiles/Output/tiger_100dpi_rot90.raw" atomically: NO];
128
129 NSLog(@"Example 3: tiger_100dpi_rot90.raw");
130 [draw SetRotate: e_pt0]; // Disable image rotation for remaining samples.
131
132 //--------------------------------------------------------------------------------
133 // Example 4) Convert PDF page to a fixed image size. Also illustrates some
134 // other features in PDFDraw class such as rotation, image stretching, exporting
135 // to grayscale, or monochrome.
136
137 // Initialize render 'gray_hint' parameter, that is used to control the
138 // rendering process. In this case we tell the rasterizer to export the image as
139 // 1 Bit Per Component (BPC) image.
140 PTObj *mono_hint=[hint_set CreateDict];
141 [mono_hint PutNumber: @"BPC" value: 1];
142
143 // SetImageSize can be used instead of SetDPI() to adjust page scaling
144 // dynamically so that given image fits into a buffer of given dimensions.
145 [draw SetImageSize: 1000 height: 1000 preserve_aspect_ratio: YES]; // Set the output image to be 1000 wide and 1000 pixels tall
146 [draw ExportWithObj: page filename: @"../../TestFiles/Output/tiger_1000x1000.png" format: @"PNG" encoder_params: mono_hint];
147 NSLog(@"Example 4: tiger_1000x1000.png");
148
149 [draw SetImageSize: 200 height: 400 preserve_aspect_ratio: YES]; // Set the output image to be 200 wide and 300 pixels tall
150 [draw SetRotate: e_pt180]; // Rotate all pages 90 degrees clockwise.
151
152 // 'gray_hint' tells the rasterizer to export the image as grayscale.
153 PTObj *gray_hint=[hint_set CreateDict];
154 [gray_hint PutName: @"ColorSpace" name: @"Gray"];
155
156 [draw ExportWithObj: page filename: @"../../TestFiles/Output/tiger_200x400_rot180.png" format: @"PNG" encoder_params: gray_hint];
157 NSLog(@"Example 4: tiger_200x400_rot180.png");
158
159 [draw SetImageSize: 400 height: 200 preserve_aspect_ratio: NO]; // The third parameter sets 'preserve-aspect-ratio' to false.
160 [draw SetRotate: e_pt0]; // Disable image rotation.
161 [draw Export:page filename: @"../../TestFiles/Output/tiger_400x200_stretch.jpg" format: @"JPEG"];
162 NSLog(@"Example 4: tiger_400x200_stretch.jpg");
163
164 //--------------------------------------------------------------------------------
165 // Example 5) Zoom into a specific region of the page and rasterize the
166 // area at 200 DPI and as a thumbnail (i.e. a 50x50 pixel image).
167 PTPDFRect *zoom_rect = [[PTPDFRect alloc] initWithX1: 216 y1: 522 x2: 330 y2: 600];
168 [page SetCropBox: zoom_rect]; // Set the page crop box.
169
170 // Select the crop region to be used for drawing.
171 [draw SetPageBox: e_ptcrop];
172 [draw SetDPI: 900]; // Set the output image resolution to 900 DPI.
173 [draw Export:page filename: @"../../TestFiles/Output/tiger_zoom_900dpi.png" format: @"PNG"];
174 NSLog(@"Example 5: tiger_zoom_900dpi.png");
175
176 // -------------------------------------------------------------------------------
177 // Example 6)
178 [draw SetImageSize: 50 height: 50 preserve_aspect_ratio: YES]; // Set the thumbnail to be 50x50 pixel image.
179 [draw Export:page filename: @"../../TestFiles/Output/tiger_zoom_50x50.png" format: @"PNG"];
180 NSLog(@"Example 6: tiger_zoom_50x50.png");
181 }
182 @catch(NSException *e)
183 {
184 NSLog(@"%@", e.reason);
185 }
186
187 PTObj *cmyk_hint = [hint_set CreateDict];
188 [cmyk_hint PutName: @"ColorSpace" name: @"CMYK"];
189
190 //--------------------------------------------------------------------------------
191 // Example 7) Convert the first PDF page to CMYK TIFF at 92 DPI.
192 // A three step tutorial to convert PDF page to an image
193 @try
194 {
195 // A) Open the PDF document.
196 PTPDFDoc *doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/tiger.pdf"];
197 // Initialize the security handler, in case the PDF is encrypted.
198 [doc InitSecurityHandler];
199
200 // B) The output resolution is set to 92 DPI.
201 [draw SetDPI: 92];
202
203 // C) Rasterize the first page in the document and save the result as TIFF.
204 PTPage *pg = [doc GetPage: 1];
205 [draw ExportWithObj: pg filename: @"../../TestFiles/Output/out1.tif" format: @"TIFF" encoder_params: cmyk_hint];
206 NSLog(@"Example 7: out1.tif");
207 }
208 @catch(NSException *e)
209 {
210 NSLog(@"%@", e.reason);
211 }
212
213 //--------------------------------------------------------------------------------
214 // Example 8) PDFRasterizer can be used for more complex rendering tasks, such as
215 // strip by strip or tiled document rendering. In particular, it is useful for
216 // cases where you cannot simply modify the page crop box (interactive viewing,
217 // parallel rendering). This example shows how you can rasterize the south-west
218 // quadrant of a page.
219 @try
220 {
221 // A) Open the PDF document.
222 PTPDFDoc* doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/tiger.pdf"];
223 // Initialize the security handler, in case the PDF is encrypted.
224 [doc InitSecurityHandler];
225
226 // B) Get the page matrix
227 PTPage* pg = [doc GetPage: 1];
228 PTBox box = e_ptcrop;
229 PTMatrix2D* mtx = [pg GetDefaultMatrix: YES box_type: box angle: e_pt0];
230 // We want to render a quadrant, so use half of width and height
231 const double pg_w = [pg GetPageWidth: box] / 2;
232 const double pg_h = [pg GetPageHeight: box] / 2;
233
234 // C) Scale matrix from PDF space to buffer space
235 const double dpi = 96.0f;
236 const double scale = dpi / 72.0f; // PDF space is 72 dpi
237 const size_t buf_w = floor(scale * pg_w);
238 const size_t buf_h = floor(scale * pg_h);
239 const int bytes_per_pixel = 4; // RGBA buffer
240 const size_t buf_size = buf_w * buf_h * bytes_per_pixel;
241 [mtx Translate: 0 v: -pg_h]; // translate by '-pg_h' since we want south-west quadrant
242 //mtx = Common::Matrix2D(scale, 0, 0, scale, 0, 0) * mtx;
243 PTMatrix2D* scale_mtx = [[PTMatrix2D alloc] initWithA: scale b: 0 c: 0 d: scale h: 0 v:0];
244 mtx = [scale_mtx Multiply: mtx];
245
246 // D) Rasterize page into memory buffer, according to our parameters
247 PTPDFRasterizer* rast = [[PTPDFRasterizer alloc] initWithType: e_ptBuiltIn];
248 NSData* buf = [rast Rasterize: pg width:(int)buf_w height:(int)buf_h stride: (int)buf_w * bytes_per_pixel num_comps: bytes_per_pixel demult: YES device_mtx: mtx clip: Nil scrl_clip_regions: Nil];
249
250 // buf now contains raw BGRA bitmap.
251 NSLog(@"Example 8: Successfully rasterized into memory buffer.");
252 }
253 @catch (NSException* e)
254 {
255 NSLog(@"%@", e.reason);
256 }
257
258
259
260 //--------------------------------------------------------------------------------
261 // Example 9) Export raster content to PNG using different image smoothing settings.
262 @try
263 {
264 PTPDFDoc* text_doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/lorem_ipsum.pdf"];
265 [text_doc InitSecurityHandler];
266
267 [draw SetImageSmoothing:false hq_image_resampling:false];
268 [draw Export:[[text_doc GetPageIterator:1] Current] filename: @"../../TestFiles/Output/raster_text_no_smoothing.png" format:@"PNG"];
269 NSLog(@"Example 9 a): raster_text_no_smoothing.png. Done.");
270
271 [draw SetImageSmoothing:true hq_image_resampling:false];
272 [draw Export:[[text_doc GetPageIterator:1] Current] filename: @"../../TestFiles/Output/raster_text_smoothed.png" format:@"PNG"];
273 NSLog(@"Example 9 b): raster_text_smoothed.png. Done.");
274
275 [draw SetImageSmoothing:true hq_image_resampling:true];
276 [draw Export:[[text_doc GetPageIterator:1] Current] filename: @"../../TestFiles/Output/raster_text_high_quality.png" format:@"PNG"];
277 NSLog(@"Example 9 c): raster_text_high_quality.png. Done.");
278 }
279 @catch (NSException *e)
280 {
281 NSLog(@"%@", e.reason);
282 }
283
284
285 //--------------------------------------------------------------------------------
286 // Example 10) Export separations directly, without conversion to an output colorspace
287 @try
288 {
289 PTPDFDoc* separation_doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/op_blend_test.pdf"];
290 [separation_doc InitSecurityHandler];
291
292 PTObj* separation_hint = [hint_set CreateDict];
293 [separation_hint PutName:@"ColorSpace" name:@"Separation"];
294 [draw SetDPI:96];
295 [draw SetImageSmoothing:true hq_image_resampling:true];
296 [draw SetOverprint: e_ptop_on];
297
298 [draw Export:[[separation_doc GetPageIterator:1] Current] filename: @"../../TestFiles/Output/merged_separations.png" format: @"PNG"];
299 NSLog(@"Example 10 a): merged_separations.png. Done.");
300
301 [draw ExportWithObj:[[separation_doc GetPageIterator:1] Current] filename: @"../../TestFiles/Output/separation" format: @"PNG" encoder_params: separation_hint];
302 NSLog(@"Example 10 b): separation_[ink].png. Done.");
303
304 [draw ExportWithObj:[[separation_doc GetPageIterator:1] Current] filename: @"../../TestFiles/Output/separation_NChannel.tif" format: @"TIFF" encoder_params: separation_hint];
305 NSLog(@"Example 10 c): separation_NChannel.tif. Done.");
306 }
307 @catch (NSException *e)
308 {
309 NSLog(@"%@", e.reason);
310 }
311
312
313
314 }
315 @catch(NSException *e)
316 {
317 NSLog(@"%@", e.reason);
318 }
319
320
321 [PTPDFNet Terminate: 0];
322
323 return 0;
324 }
325}

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales