How can I get PDF page width and height in iPad? Any document or suggestions on how I can find this information?
I was using the answers here until I realised a one-liner for this
CGRect pageRect = CGPDFPageGetBoxRect(pdf, kCGPDFMediaBox);
// Which you can convert to size as
CGSize size = pageRect.size;
Used in Apple's sample ZoomingPDFViewer app
Here's the code to do it; also to convert a point on the page from PDF coordinates to iOS coordinates. See also Get PDF hyperlinks on iOS with Quartz
#import <CoreGraphics/CoreGraphics.h>
. . . . . . . . . . .
NSString *pathToPdfDoc = [[NSBundle mainBundle] pathForResource:@"Test2" offType:@"pdf"];
NSURL *pdfUrl = [NSURL fileURLWithPath:pathToPdfDoc];
CGPDFDocumentRef document = CGPDFDocumentCreateWithURL((CFURLRef)pdfUrl);
CGPDFPageRef page = CGPDFDocumentGetPage(document, 1); // assuming all the pages are the same size!
// code from https://mcmap.net/q/88239/-get-pdf-hyperlinks-on-ios-with-quartz,
// suitably amended
CGPDFDictionaryRef pageDictionary = CGPDFPageGetDictionary(page);
//******* getting the page size
CGPDFArrayRef pageBoxArray;
if(!CGPDFDictionaryGetArray(pageDictionary, "MediaBox", &pageBoxArray)) {
return; // we've got something wrong here!!!
}
int pageBoxArrayCount = CGPDFArrayGetCount( pageBoxArray );
CGPDFReal pageCoords[4];
for( int k = 0; k < pageBoxArrayCount; ++k )
{
CGPDFObjectRef pageRectObj;
if(!CGPDFArrayGetObject(pageBoxArray, k, &pageRectObj))
{
return;
}
CGPDFReal pageCoord;
if(!CGPDFObjectGetValue(pageRectObj, kCGPDFObjectTypeReal, &pageCoord)) {
return;
}
pageCoords[k] = pageCoord;
}
NSLog(@"PDF coordinates -- bottom left x %f ",pageCoords[0]); // should be 0
NSLog(@"PDF coordinates -- bottom left y %f ",pageCoords[1]); // should be 0
NSLog(@"PDF coordinates -- top right x %f ",pageCoords[2]);
NSLog(@"PDF coordinates -- top right y %f ",pageCoords[3]);
NSLog(@"-- i.e. PDF page is %f wide and %f high",pageCoords[2],pageCoords[3]);
// **** now to convert a point on the page from PDF coordinates to iOS coordinates.
double PDFHeight, PDFWidth;
PDFWidth = pageCoords[2];
PDFHeight = pageCoords[3];
// the size of your iOS view or image into which you have rendered your PDF page
// in this example full screen iPad in portrait orientation
double iOSWidth = 768.0;
double iOSHeight = 1024.0;
// the PDF co-ordinate values you want to convert
double PDFxval = 89; // or whatever
double PDFyval = 520; // or whatever
// the iOS coordinate values
int iOSxval, iOSyval;
iOSxval = (int) PDFxval * (iOSWidth/PDFWidth);
iOSyval = (int) (PDFHeight - PDFyval) * (iOSHeight/PDFHeight);
NSLog(@"PDF: %f %f",PDFxval,PDFyval);
NSLog(@"iOS: %i %i",iOSxval,iOSyval);
The following method returns the height of the first pdf page scaled according to a webview:
-(NSInteger) pdfPageSize:(NSData*) pdfData{
CGPDFDocumentRef document = CGPDFDocumentCreateWithProvider(CGDataProviderCreateWithCFData((__bridge CFDataRef)pdfData));
CGPDFPageRef page = CGPDFDocumentGetPage(document, 1);
CGRect pageRect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
double pdfHeight, pdfWidth;
pdfWidth = pageRect.size.width;
pdfHeight = pageRect.size.height;
double iOSWidth = _webView.frame.size.width;
double iOSHeight = _webView.frame.size.height;
double scaleWidth = iOSWidth/pdfWidth;
double scaleHeight = iOSHeight/pdfHeight;
double scale = scaleWidth > scaleHeight ? scaleWidth : scaleHeight;
NSInteger finalHeight = pdfHeight * scale;
NSLog(@"MediaRect %f, %f, %f, %f", pageRect.origin.x, pageRect.origin.y, pageRect.size.width, pageRect.size.height);
NSLog(@"Scale: %f",scale);
NSLog(@"Final Height: %i", finalHeight);
return finalHeight;
}
It's a lot smaller than Donal O'Danachair's and does basically the same thing. You could easily adapt it to your View size and to return the width along with the height.
Swift 3.x (based on answer provided by Ege Akpinar)
let pageRect = pdfPage.getBoxRect(CGPDFBox.mediaBox) // where pdfPage is a CGPDFPage
let pageSize = pageRect.size
A more full example showing how to extract the dimensions of page in a PDF file:
/**
Returns the dimensions of a PDF page.
- Parameter pdfURL: The URL of the PDF file.
- Parameter pageNumber: The number of the page to obtain dimensions (Note: page numbers start from `1`, not `0`)
*/
func pageDimension(pdfURL: URL, pageNumber: Int) -> CGSize? {
// convert URL to NSURL which is toll-free-briged with CFURL
let url = pdfURL as NSURL
guard let pdf = CGPDFDocument(url) else { return nil }
guard let pdfPage = pdf.page(at: pageNumber) else { return nil }
let pageRect = pdfPage.getBoxRect(CGPDFBox.mediaBox)
let pageSize = pageRect.size
return pageSize
}
let url = Bundle.main.url(forResource: "file", withExtension: "pdf")!
let dimensions = pageDimension(pdfURL: url, pageNumber: 1)
print(dimensions ?? "Cannot get dimensions")
I took Donal O'Danachair's answer and made a few modifications so the rect size is also scaled to the pdf's size. This code snipped actually gets all the annotations off a pdf page and creates the CGRect from the PDF rect. Part of the code is form the answer to a question Donal commented on his.
CGPDFDictionaryRef pageDictionary = CGPDFPageGetDictionary(pageRef);
CGFloat boundsWidth = pdfView.bounds.size.width;
CGFloat boundsHeight = pdfView.bounds.size.height;
CGRect cropBoxRect = CGPDFPageGetBoxRect(pageRef, kCGPDFCropBox);
CGRect mediaBoxRect = CGPDFPageGetBoxRect(pageRef, kCGPDFMediaBox);
CGRect effectiveRect = CGRectIntersection(cropBoxRect, mediaBoxRect);
CGFloat effectiveWidth = effectiveRect.size.width;
CGFloat effectiveHeight = effectiveRect.size.height;
CGFloat widthScale = (boundsWidth / effectiveWidth);
CGFloat heightScale = (boundsHeight / effectiveHeight);
CGFloat pdfScale = (widthScale < heightScale) ? widthScale : heightScale;
CGFloat x_offset = ((boundsWidth - (effectiveWidth * pdfScale)) / 2.0f);
CGFloat y_offset = ((boundsHeight - (effectiveHeight * pdfScale)) / 2.0f);
y_offset = (boundsHeight - y_offset); // Co-ordinate system adjust
//CGFloat x_translate = (x_offset - effectiveRect.origin.x);
//CGFloat y_translate = (y_offset + effectiveRect.origin.y);
CGPDFArrayRef outputArray;
if(!CGPDFDictionaryGetArray(pageDictionary, "Annots", &outputArray)) {
return;
}
int arrayCount = CGPDFArrayGetCount( outputArray );
if(!arrayCount) {
//continue;
}
self.annotationRectArray = [[NSMutableArray alloc] initWithCapacity:arrayCount];
for( int j = 0; j < arrayCount; ++j ) {
CGPDFObjectRef aDictObj;
if(!CGPDFArrayGetObject(outputArray, j, &aDictObj)) {
return;
}
CGPDFDictionaryRef annotDict;
if(!CGPDFObjectGetValue(aDictObj, kCGPDFObjectTypeDictionary, &annotDict)) {
return;
}
CGPDFDictionaryRef aDict;
if(!CGPDFDictionaryGetDictionary(annotDict, "A", &aDict)) {
return;
}
CGPDFStringRef uriStringRef;
if(!CGPDFDictionaryGetString(aDict, "URI", &uriStringRef)) {
return;
}
CGPDFArrayRef rectArray;
if(!CGPDFDictionaryGetArray(annotDict, "Rect", &rectArray)) {
return;
}
int arrayCount = CGPDFArrayGetCount( rectArray );
CGPDFReal coords[4];
for( int k = 0; k < arrayCount; ++k ) {
CGPDFObjectRef rectObj;
if(!CGPDFArrayGetObject(rectArray, k, &rectObj)) {
return;
}
CGPDFReal coord;
if(!CGPDFObjectGetValue(rectObj, kCGPDFObjectTypeReal, &coord)) {
return;
}
coords[k] = coord;
}
char *uriString = (char *)CGPDFStringGetBytePtr(uriStringRef);
//******* getting the page size
CGPDFArrayRef pageBoxArray;
if(!CGPDFDictionaryGetArray(pageDictionary, "MediaBox", &pageBoxArray)) {
return; // we've got something wrong here!!!
}
int pageBoxArrayCount = CGPDFArrayGetCount( pageBoxArray );
CGPDFReal pageCoords[4];
for( int k = 0; k < pageBoxArrayCount; ++k )
{
CGPDFObjectRef pageRectObj;
if(!CGPDFArrayGetObject(pageBoxArray, k, &pageRectObj))
{
return;
}
CGPDFReal pageCoord;
if(!CGPDFObjectGetValue(pageRectObj, kCGPDFObjectTypeReal, &pageCoord)) {
return;
}
pageCoords[k] = pageCoord;
}
#if DEBUG
NSLog(@"PDF coordinates -- bottom left x %f ",pageCoords[0]); // should be 0
NSLog(@"PDF coordinates -- bottom left y %f ",pageCoords[1]); // should be 0
NSLog(@"PDF coordinates -- top right x %f ",pageCoords[2]);
NSLog(@"PDF coordinates -- top right y %f ",pageCoords[3]);
NSLog(@"-- i.e. PDF page is %f wide and %f high",pageCoords[2],pageCoords[3]);
#endif
// **** now to convert a point on the page from PDF coordinates to iOS coordinates.
double PDFHeight, PDFWidth;
PDFWidth = pageCoords[2];
PDFHeight = pageCoords[3];
// the size of your iOS view or image into which you have rendered your PDF page
// in this example full screen iPad in portrait orientation
double iOSWidth = 768.0;
double iOSHeight = 1024.0;
// the PDF co-ordinate values you want to convert
double PDFxval = coords[0]; // or whatever
double PDFyval = coords[3]; // or whatever
double PDFhval = (coords[3]-coords[1]);
double PDFwVal = coords[2]-coords[0];
// the iOS coordinate values
CGFloat iOSxval, iOSyval,iOShval,iOSwval;
iOSxval = PDFxval * (iOSWidth/PDFWidth);
iOSyval = (PDFHeight - PDFyval) * (iOSHeight/PDFHeight);
iOShval = PDFhval *(iOSHeight/PDFHeight);// here I scale the width and height
iOSwval = PDFwVal *(iOSWidth/PDFWidth);
#if DEBUG
NSLog(@"PDF: { {%f %f }, { %f %f } }",PDFxval,PDFyval,PDFwVal,PDFhval);
NSLog(@"iOS: { {%f %f }, { %f %f } }",iOSxval,iOSyval,iOSwval,iOShval);
#endif
NSString *uri = [NSString stringWithCString:uriString encoding:NSUTF8StringEncoding];
CGRect rect = CGRectMake(iOSxval,iOSyval,iOSwval,iOShval);// create the rect and use it as you wish
© 2022 - 2024 — McMap. All rights reserved.