views:

695

answers:

1

Is there a way to load a PDF into a CALayer (or CATiledLayer) offscreen and then just display it when required? The solution should also support zooming at the required resolution.

Update
Just to clarify - I want the pdf to remain vector based.

+1  A: 

Note : you told that You need to load PDF into CALayer. But Here, I have the solution for loading entire pdf pages into images. Once images are in an array, you can view any of them as & when required. Add comment if you have any doubts.

  • You just have to copy & paste following code. It will almost work for you. I have tested.

First of all put following method above the implementation of your view controller.

NSMutableArray *aRefImgs; // global variable.
void setRefImgs(NSMutableArray *ref){
    aRefImgs=ref;
}

NSMutableArray* ImgArrRef(){
    return aRefImgs;
}
CGPDFDocumentRef MyGetPDFDocumentRef (const char *filename) {
    CFStringRef path;
    CFURLRef url;
    CGPDFDocumentRef document;
    path = CFStringCreateWithCString (NULL, filename,kCFStringEncodingUTF8);
    url = CFURLCreateWithFileSystemPath (NULL, path, kCFURLPOSIXPathStyle, 0);
    CFRelease (path);
    document = CGPDFDocumentCreateWithURL (url);// 2
    CFRelease(url);
    int count = CGPDFDocumentGetNumberOfPages (document);// 3
    if (count == 0) {
        printf("`%s' needs at least one page!", filename);
        return NULL;
    }
    return document;
}

void MyDisplayPDFPage (CGContextRef myContext,size_t pageNumber,const char *filename, CGPDFOperatorTableRef tblRef, NSMutableString *mainStr) {
    CGPDFDocumentRef document;
    CGPDFPageRef page;
    document = MyGetPDFDocumentRef (filename);// 1
    totalPages=CGPDFDocumentGetNumberOfPages(document);
    page = CGPDFDocumentGetPage (document, pageNumber);// 2
    CGContextDrawPDFPage (myContext, page);// 3
    CGContextTranslateCTM(myContext, 0, 20);
    CGContextScaleCTM(myContext, 1.0, -1.0);
    CGPDFDocumentRelease (document);// 4
}

Now, place following code in your viewController.m file.

-(void)viewDidLoad {
    filePath=[[NSString alloc] initWithString:[[NSBundle mainBundle] pathForResource:@"roadie" ofType:@"pdf"]];

    CGPDFDocumentRef d=MyGetPDFDocumentRef([filePath UTF8String]);

    size_t nos=CGPDFDocumentGetNumberOfPages(d); 
    totalPages=nos;
    arrImgs=[[NSMutableArray alloc] init]; // arrImgs variable declared in viewController.h file.
setRefImgs(arrImgs);
int i;
for(i=0;i<nos;i++){
    UIGraphicsBeginImageContext(CGSizeMake(720, 720));
    MyDisplayPDFPage(UIGraphicsGetCurrentContext(), i+1, [filePath UTF8String],myTable,mainString);
    UIImage *tmp=UIGraphicsGetImageFromCurrentImageContext();
    UIImage *t2=[tmp rotate:UIImageOrientationDownMirrored];
    [arrPDFImgs addObject:t2];
    UIImageView *imgV=[[UIImageView alloc] initWithFrame:CGRectMake(scrPDFImages.frame.size.width * i, 0, scrPDFImages.frame.size.width, scrPDFImages.frame.size.height)];
    [imgV setContentMode:UIViewContentModeScaleToFill];
    [imgV setImage:t2];
    [scrPDFImages addSubview:imgV]; 
            // scrPDFImages is an array that has all images 
            // per page one image from pdf document
    [imgV release];
    UIGraphicsPopContext();
    }
}

You might need image orientation - i also have placed entire class here.

@interface UIImage (WBImage)
// rotate UIImage to any angle
-(UIImage*)rotate:(UIImageOrientation)orient;
@end

@implementation UIImage (WBImage)


static inline CGFloat degreesToRadians(CGFloat degrees)
{
    return M_PI * (degrees / 180.0);
}

static inline CGSize swapWidthAndHeight(CGSize size)
{
    CGFloat  swap = size.width;

    size.width  = size.height;
    size.height = swap;

    return size;
}


-(UIImage*)rotate:(UIImageOrientation)orient
{
    CGRect             bnds = CGRectZero;
    UIImage*           copy = nil;
    CGContextRef       ctxt = nil;
    CGRect             rect = CGRectZero;
    CGAffineTransform  tran = CGAffineTransformIdentity;

    bnds.size = self.size;
    rect.size = self.size;

    switch (orient)
    {
        case UIImageOrientationUp:
            return self;

        case UIImageOrientationUpMirrored:
            tran = CGAffineTransformMakeTranslation(rect.size.width, 0.0);
            tran = CGAffineTransformScale(tran, -1.0, 1.0);
            break;

        case UIImageOrientationDown:
            tran = CGAffineTransformMakeTranslation(rect.size.width,
                                                    rect.size.height);
            tran = CGAffineTransformRotate(tran, degreesToRadians(180.0));
            break;

        case UIImageOrientationDownMirrored:
            tran = CGAffineTransformMakeTranslation(0.0, rect.size.height);
            tran = CGAffineTransformScale(tran, 1.0, -1.0);
            break;

        case UIImageOrientationLeft:
            bnds.size = swapWidthAndHeight(bnds.size);
            tran = CGAffineTransformMakeTranslation(0.0, rect.size.width);
            tran = CGAffineTransformRotate(tran, degreesToRadians(-90.0));
            break;

        case UIImageOrientationLeftMirrored:
            bnds.size = swapWidthAndHeight(bnds.size);
            tran = CGAffineTransformMakeTranslation(rect.size.height,
                                                    rect.size.width);
            tran = CGAffineTransformScale(tran, -1.0, 1.0);
            tran = CGAffineTransformRotate(tran, degreesToRadians(-90.0));
            break;

        case UIImageOrientationRight:
            bnds.size = swapWidthAndHeight(bnds.size);
            tran = CGAffineTransformMakeTranslation(rect.size.height, 0.0);
            tran = CGAffineTransformRotate(tran, degreesToRadians(90.0));
            break;

        case UIImageOrientationRightMirrored:
            bnds.size = swapWidthAndHeight(bnds.size);
            tran = CGAffineTransformMakeScale(-1.0, 1.0);
            tran = CGAffineTransformRotate(tran, degreesToRadians(90.0));
            break;

        default:
            // orientation value supplied is invalid
            assert(false);
            return nil;
    }

    UIGraphicsBeginImageContext(bnds.size);
    ctxt = UIGraphicsGetCurrentContext();

    switch (orient)
    {
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            CGContextScaleCTM(ctxt, -1.0, 1.0);
            CGContextTranslateCTM(ctxt, -rect.size.height, 0.0);
            break;

        default:
            CGContextScaleCTM(ctxt, 1.0, -1.0);
            CGContextTranslateCTM(ctxt, 0.0, -rect.size.height);
            break;
    }

    CGContextConcatCTM(ctxt, tran);
    CGContextDrawImage(ctxt, rect, self.CGImage);

    copy = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return copy;
}


@end
sugar
HOw can you control the size/quality of the image created?
Jean
Image will be as good as pdf looks.
sugar
The pdf page is vector based and looks perfect when zoomed in. In order to get the image to look decent when it is zoomed in, I need to create a version at higher resolution. How can this be done?
Jean
Please add it to your question that - you also want zooming.
sugar
I also have solution for zooming. But it will add more code in to my answer.
sugar