0

Building onto this question, I have tried to delve into CGPDF to get PDF size data without loading it into memory.

This part of iOS is very poorly documented, and searching the web only gives me some bad results about writing to pdfs.. Here is what i've tried, this doesn't result in anything else than a EXC_BAD_ACCESS on the noted line.

 NSURL *imageFileURL = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:@"a1" ofType:@"pdf"]];

CGPDFDocumentRef pdfSource = CGPDFDocumentCreateWithURL((__bridge CFURLRef)imageFileURL);
CGPDFDictionaryRef pdfProps = CGPDFDocumentGetInfo(pdfSource);

CGPDFStringRef cfValue;
CGPDFDictionaryGetString(pdfProps, kCGPDFMediaBox, &cfValue); //Crash, EXC_BAD_ACCESS

NSString *value = CFBridgingRelease(CGPDFStringCopyTextString(cfValue));
CGRect rect = CGRectFromString(value);
NSLog(@"#rekt: %@",NSStringFromCGRect(rect));

Where am I stepping wrong here?

Community
  • 1
  • 1
Oscar Apeland
  • 6,422
  • 7
  • 44
  • 92
  • The documentation isn't too bad if you're careful about using the different functions, but you need to read (at least some of) the PDF specification from Adobe as well as that defines what the rules for PDF are. Without them it's close to useless to start screwing around with PDF dictionaries and other structures... – David van Driessche Apr 11 '14 at 13:27
  • @DavidvanDriessche Probably just my fault, yeah. I'm not a pro at this in any way. Just doing this as a hobby besides school. – Oscar Apeland Apr 11 '14 at 13:30
  • 1
    Not judging, Oscar, just sharing what was a hard lesson on my side :) Hobbies are great - keep at it. – David van Driessche Apr 11 '14 at 21:53

2 Answers2

0

The CGPDFDocumentGetInfo() dictionary does not contain information about the sizes because all pages in a PDF document can have different dimensions (media box, crop box, ...). The following shows how to get the information for the first page:

CGPDFDocumentRef doc = CGPDFDocumentCreateWithURL((__bridge CFURLRef)pdfURL);
CGPDFPageRef page = CGPDFDocumentGetPage(doc, 1);
CGRect mediaBox = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
NSLog(@"#mediaBox: %@",NSStringFromCGRect(mediaBox));
CGPDFDocumentRelease(doc);

For documents with multiple pages you would have to determine the maximum over all pages in the document.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Watch out - what you're saying isn't strictly correct. The code you provide should work (as I would expect the CGPDFPageGetBoxRect function to be implemented correctly), but Mediabox (and many other properties) can be set on either an individual page or can be inherited by a page from a higher container in the page tree. – David van Driessche Apr 11 '14 at 13:25
  • Thanks, this worked for me. @DavidvanDriessche, the PDF's are only one page, so its fine. I use vector images for some formulas in this educational app. – Oscar Apeland Apr 11 '14 at 13:28
  • @DavidvanDriessche: You are right that in the PDF file format, the MediaBox can be part of the /Page object or of a parent /Pages object. From the CGPDF... API point of view, it is a property of the page because that API has no direct access to the individual objects (I think). I have updated the answer to make it (hopefully) technically correct. And yes, CGPDFPageGetBoxRect() returns the information from a parent object where appropriate. - Thanks for the feedback! – Martin R Apr 11 '14 at 13:51
0

You are passing wrong key value to CGPDFDictionaryGetString, keys are const char * and you are passing kCGPDFMediaBox which is a constant of enum CGPDFBox (defined as 0). As the documentation say CGPDFDictionaryRef keys are compared by using strcmp, so passing 0 (or NULL) as key will crash strcmp.

If you want the media box of a PDF page use CGPDFPageGetBoxRect

NSLog(@"#rekt: %@",NSStringFromCGRect(CGPDFPageGetBoxRect(aPDFPage, kCGPDFMediaBox));
Emmanuel
  • 2,897
  • 1
  • 14
  • 15