Edit PDF in iphone application - iphone

Now I am creating an application that works like 'iAnnotate PDF'
Till now I have completed reading and displaying pdf pages in UIView.
Even I am sucessful in getting TOC.
Now I want to edit PDFs, Editing includes marker, highlights and writing notes.
Now my question is how to edit? I mean do we need to create another pdf and over write it with new changes?
Or there is any way we can update single page in existing pdfs??
If yes how is that done?
If we are rewriting the entire pdf, wont that be creating overhead?

You can create/edit pdf's easily using CoreGraphics. Just create a rect defining the size, then create the context, push the context, call CFPDFContextBeginPage and start drawing like you would normally do...Here's an example:
CGRect mediaBox = CGRectMake(0, 0, 550, 800);
NSString *url = [path stringByExpandingTildeInPath];
CGContextRef ctx = CGPDFContextCreateWithURL((CFURLRef)[NSURL fileURLWithPath:url], &mediaBox, NULL);
UIGraphicsPushContext(ctx);
//Page1
CGPDFContextBeginPage(ctx, NULL);
CGContextScaleCTM(ctx, 1, -1);
CGContextTranslateCTM(ctx, 0, -mediaBox.size.height);
//name and value are NSStrings
[name drawInRect:rectName withFont:fontName];
[value drawInRect:rectValue withFont:fontValue];
[[UIImage imageNamed:#"logo.png"] drawInRect:CGRectMake(8, 15, 91, 99)];
CGPDFContextEndPage(ctx);
UIGraphicsPopContext();
CFRelease(ctx);
UPDATE
You can copy the pages you require and then do the drawing over them like this:
CGPDFDocumentRef originalDoc = NULL;
CGContextRef pdfContext = NULL;
CGRect docRect = CGRectZero;
NSURL *originalURL = [[NSBundle mainBundle] URLForResource:#"test" withExtension:#"pdf"];
NSString *newPath = #"/Users/***/Desktop/new.pdf";
CFURLRef newURL = CFURLCreateWithFileSystemPath (NULL,
(CFStringRef)newPath,
kCFURLPOSIXPathStyle,
false);
//Original doc and it's dimesnions
originalDoc = CGPDFDocumentCreateWithURL((CFURLRef)originalURL);
CGPDFPageRef firstPage = CGPDFDocumentGetPage(originalDoc, 1);
if (firstPage == NULL) {
NSLog(#"This document has no pages..Exiting.");
}
docRect = CGPDFPageGetBoxRect(firstPage, kCGPDFCropBox);
NSLog(#"%#", NSStringFromRect(docRect));
//New doc context
if (newURL != NULL) {
pdfContext = CGPDFContextCreateWithURL(newURL, &docRect, NULL);
if (pdfContext == NULL) {
NSLog(#"Error creating context");
}
CFRelease(newURL);
} else {
NSLog(#"Error creating url");
}
And then copy each page individually. In this particular example, I am adding "Bates" (numbering) to the pages.
//Copy original to new, and write bates
size_t count = CGPDFDocumentGetNumberOfPages(originalDoc);
for (size_t pageNumber = 1; pageNumber <= count; pageNumber++) {
CGPDFPageRef originalPage = CGPDFDocumentGetPage(originalDoc, pageNumber);
CGContextBeginPage (pdfContext,nil);
CGContextSetRGBFillColor(pdfContext, 0, 0, 255, 0.1);
CGContextSetRGBStrokeColor(pdfContext, 0, 0, 255, 0.5);
// Draw a circle (filled)
CGContextFillEllipseInRect(pdfContext, CGRectMake(0, 0, 25, 25));
CGContextSaveGState(pdfContext);
//flip context due to different origins
CGContextTranslateCTM(pdfContext, 0.0, (docRect.size.height - (docRect.size.height * 0.80))/2);
CGContextScaleCTM(pdfContext, 1.0, 0.8);
//copy content of template page on the corresponding page in new file
CGContextDrawPDFPage(pdfContext, originalPage);
CGContextRestoreGState(pdfContext);
//flip context back
//CGContextTranslateCTM(pdfContext, 0.0, -(docRect.size.height - (docRect.size.height * 0.80))/2);
//CGContextScaleCTM(pdfContext, 1.0, 1.25);
CGContextSetRGBFillColor(pdfContext, 0, 0, 255, 0.1);
CGContextSetRGBStrokeColor(pdfContext, 0, 0, 255, 0.5);
// Draw a circle (filled)
CGContextFillEllipseInRect(pdfContext, CGRectMake(0, 0, 25, 25));
NSString *bate = [self generateStringForCount:(int)pageNumber-1];
int fontSize = 15;
CGContextSelectFont(pdfContext, "Helvetica", fontSize, kCGEncodingMacRoman);
CGContextSetTextDrawingMode(pdfContext, kCGTextFill);
CGContextSetTextPosition(pdfContext, 0.0f, round(fontSize / 4.0f));
CGContextShowText(pdfContext, [bate UTF8String], strlen([bate UTF8String]));
CGContextEndPage(pdfContext);
}
CFRelease(pdfContext);

Maybe this idea can work in iPhone I think there is no directly way we can edit a PDF but what we can do we can produce such functionality that iAnnotate app have i.e. drawing line and text and then just save the PDF as a picture page by page in which you will include the edited page too and then you will create the PDF again by images then I think so you will get the edited PDF.

Now with the latest release of iOS, it becomes really easy to edit PDF on your iPhone.
Open PDF on your iPhone (usually on Books/ Photos)
Click on the markup tool.
From the more option at the bottom, you can choose Text, Signature, and Magnifier.
You can also add a different colour to text. But you can not edit the already existing text. I recommend you to go for some best PDF editing software.

Related

Creating a pdf which included many labels and text view full content of view in pdf

My problem is that I have to create a pdf of my screen text.My view contains a text view which is scrollable.There are many controls on my view like date label, location label etc.. and text view.I am able to create pdf of my text view fill text but I do not know how to get add the date label, location label and other things with text view in my pdf page also.
My code for pdf creation is :
CGRect savedFrame = txtView.frame;
UIGraphicsBeginImageContext(txtView.contentSize);
{
CGPoint savedContentOffset = txtView.contentOffset;
txtView.contentOffset = CGPointZero;
txtView.frame = CGRectMake(0, 0, txtJEntry.contentSize.width, txtView.contentSize.height);
CGRect f = txtView.frame;
CGContextRef ctx = CGPDFContextCreateWithURL((__bridge CFURLRef)[NSURL fileURLWithPath:newFilePath isDirectory:NO], &f, NULL);
CGPDFContextBeginPage(ctx, NULL);
CGContextScaleCTM(ctx, 1, -1);
CGContextTranslateCTM(ctx, 0, -txtView.frame.size.height);
[txtJEntry.layer renderInContext:ctx];
CGPDFContextEndPage(ctx);
CFRelease(ctx);
txtJEntry.contentOffset = savedContentOffset;
txtJEntry.frame = savedFrame;
}
UIGraphicsEndImageContext();
As shown in the image , it is screen shot of my view.I need to add the weather, location stars and date in my pdf and as is it shown in the image means the position of these labels should also be same in the pdf.
I cannot take the screenshot of my entire screen because the text view text is scrollable and had more data .
Please help me in how to show these contents also in my pdf.
Any suggestions would be highly appreciated.
Thanks in advance!
From my understanding you want to take the entire contents of your UIView and turn it into a PDF. I have a category for UIView that renders everything on the view into a PDF file. I am successfully using it in one of my Applications.
//UIView+RenderPDF.h
#interface UIView (RenderPDF)
- (void)renderInPDFFile:(NSString*)path;
#end
//UIView+RenderPDF.m
#import "UIView+RenderPDF.h"
#import <QuartzCore/QuartzCore.h>
#implementation UIView (RenderPDF)
- (void)renderInPDFFile:(NSString*)path {
CGRect mediaBox = self.bounds;
CGContextRef ctx = CGPDFContextCreateWithURL((CFURLRef)[NSURL fileURLWithPath:path isDirectory:NO], &mediaBox, NULL);
CGPDFContextBeginPage(ctx, NULL);
CGContextScaleCTM(ctx, 1, -1);
CGContextTranslateCTM(ctx, 0, -mediaBox.size.height);
[self.layer renderInContext:ctx];
CGPDFContextEndPage(ctx);
CFRelease(ctx);
}
#end
Now, In order to use it, once you #import UIView+RenderPDF.h all you have to do is
NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString* documentDirectory = [documentDirectories objectAtIndex:0];
NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"export.pdf"]];
[someView renderInPDFFile:documentDirectoryFilename];
Resulting in export.pdf being saved to your Documents directory. Screenshot of All elements on your view into a PDF file.
Hope this helps!

saving image from a page of CGPDfDocument is not perfectly fitted in UIImageview

I am having some trouble with saving a PDF page as UIImage...the pdf is loaded from the internet and it has one page(original PDF has been splitted in sever)...but the converted image sometimes is cropped...sometimes it is small and leave white space when it is putted on UIImageview...
here is the code
-(UIImage *)imageFromPdf:(NSString *) pdfUrl{
NSURL *pdfUrlStr=[NSURL URLWithString:pdfUrl];
CFURLRef docURLRef=(CFURLRef)pdfUrlStr;
UIGraphicsBeginImageContext(CGSizeMake(768, 1024)); //840, 960
NSLog(#"save begin");
CGContextRef context = UIGraphicsGetCurrentContext();
//CFURLRef pdfURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("/file.pdf"), NULL, NULL);
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL(docURLRef);
NSLog(#"save complete");
CGContextTranslateCTM(context, 0.0, 900);//320
CGContextScaleCTM(context, 1.0, -1.0);
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1);
CGContextSaveGState(context);
CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform(page, kCGPDFCropBox, CGRectMake(0, 0, 768, 1024), 0, true);
CGContextConcatCTM(context, pdfTransform);
CGContextDrawPDFPage(context, page);
CGContextRestoreGState(context);
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return resultingImage;
}
btw I have prepared my UIImageview by coding like this
self.PDFImageVIew.contentMode = UIViewContentModeScaleAspectFit;
self.PDFImageVIew.clipsToBounds = YES;
I just want this image perfectly fitted on UIImageview and may be its reducing the quality of image...can you have suggesion how can I keep the quality also? please help and give me some suggestion
thanks
CGContextTranslateCTM(context, 0.0, 900);//320
Here generally last parameter of translate operation should be the height of context or height of rectangle for which you creating image. So, i think it should be 1024(You have taken height of image context is 1024 so here i am assuming that status bar is not present). This may eliminate the issue of cropping. Some more things that i have noted on your code you should have to save the state of graphics before any operation on context. You have are saving it but after few operations.
Above code will try to make it height fit so if height of actual page is bigger than your context height then it will be scaled down. so you can obviously see white space around page.
One more thing if your original pdf page have white space in it then there is no way to eliminate it as far as i know.

Convert pdf file to text file

Hi all I am working on Objective-C. my previous Question was How can I edit PDF files in an iOS application?
after a lot of googling I found out the following. display the pdf in UIWebView, extract the data using C/javascript and edit it. I am still not sure about this procedure. now what I have planned is
1) display the pdf
2) when user wants to edit the pdf I covert the pdf to text and allow him to edit it
3) tryin to save wil convert the content back to pdf.
is this a gud way to proceed?? im k with step 1. now how do i convert pdf--> text and text-->pdf.
thanks in advance
When you load a custom document type (doc, ppt, pdf, etc) into a UIWebView, the webview returns a nil HTML string, even via javascript. There's a few suggestions for extracting PDF text here.
But turning the string back into a PDF is different. If you want to retain the formatting of the original PDF, I'm rather sure that's impossible because NSAttributedString on iOS doesn't do much. But this will work for plain text or NSAttributedString, if its possible:
NSData *PDFDataFromString(NSString *str) {
NSMutableData *data = [NSMutableData data];
//Create an NSAttributedString for CoreText. If you find a way to translate
//PDF into an NSAttributedString, you can skip this step and simply use an
//NSAttributedString for this method's argument.
NSAttributedString* string = [[[NSAttributedString alloc] initWithString:str] autorelease];
//612 and 792 are the dimensions of the paper in pixels. (8.5" x 11")
CGRect paperRect = CGRectMake(0.0, 0.0, 612, 792);
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef) string);
CGSize requiredSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, [string length]), NULL, CGSizeMake(paperRect.size.width - 144, 1e40), NULL);
//Subtract the top and bottom margins (72 and 72), so they aren't factored in page count calculations.
NSUInteger pageCount = ceill(requiredSize.height / (paperRect.size.height - 144));
CFIndex resumePageIndex = 0;
UIGraphicsBeginPDFContextToData(data, paperRect, nil);
for(NSUInteger i = 0; i < pageCount; i++)
{
//After calculating the required number of pages, break up the string and
//draw them into sequential pages.
UIGraphicsBeginPDFPage();
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextSaveGState (currentContext);
CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity);
CGMutablePathRef framePath = CGPathCreateMutable();
//72 and 72 are the X and Y margins of the page in pixels.
CGPathAddRect(framePath, NULL, CGRectInset(paperRect, 72.0, 72.0));
CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, CFRangeMake(resumePageIndex, 0), framePath, NULL);
resumePageIndex += CTFrameGetVisibleStringRange(frameRef).length;
CGPathRelease(framePath);
CGContextTranslateCTM(currentContext, 0, paperRect.size.height);
CGContextScaleCTM(currentContext, 1.0, -1.0);
CTFrameDraw(frameRef, currentContext);
CFRelease(frameRef);
CGContextRestoreGState (currentContext);
}
CFRelease(framesetter);
UIGraphicsEndPDFContext();
return data;
}

Creating pdf Thumbnail in iphone

I am new to Objective-c iPhone programming. I have an application in which I display a PDF in my UIWebView successfully, but now I want to create a thumbnail of my PDF. My PDF is stored in my resource folder.
So please give me code for how I can show a thumbnail of my PDF. My code is for displaying PDF is which is taken in button function:
-(void)show:(id)sender {
pdfView.autoresizesSubviews = NO;
pdfView.scalesPageToFit=YES;
pdfView.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);
[pdfView setDelegate:self];
NSString *path = [[NSBundle mainBundle] pathForResource:#"com" ofType:#"pdf"];
NSLog(#"Path of res is%#",path);
NSURL *url = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[pdfView loadRequest:request];
}
try the following method:
- (UIImage *)imageFromPDFWithDocumentRef:(CGPDFDocumentRef)documentRef {
CGPDFPageRef pageRef = CGPDFDocumentGetPage(documentRef, 1);
CGRect pageRect = CGPDFPageGetBoxRect(pageRef, kCGPDFCropBox);
UIGraphicsBeginImageContext(pageRect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, CGRectGetMinX(pageRect),CGRectGetMaxY(pageRect));
CGContextScaleCTM(context, 1, -1);
CGContextTranslateCTM(context, -(pageRect.origin.x), -(pageRect.origin.y));
CGContextDrawPDFPage(context, pageRef);
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return finalImage;
}
Swift 3
(Thanks to Prine for Swift 2!)
func getPdfThumb(url:NSURL, pageBase1:Int) -> UIImage? {
guard let document = CGPDFDocument(url as CFURL) else { return nil }
guard let firstPage = document.page(at: pageBase1) else { return nil }
let width:CGFloat = 240.0;
var pageRect:CGRect = firstPage.getBoxRect(.mediaBox)
let pdfScale:CGFloat = width/pageRect.size.width
pageRect.size = CGSize(width: pageRect.size.width*pdfScale, height: pageRect.size.height*pdfScale)
pageRect.origin = CGPoint.zero
UIGraphicsBeginImageContext(pageRect.size)
let context:CGContext = UIGraphicsGetCurrentContext()!
// White background
context.setFillColor(red: 1.0,green: 1.0,blue: 1.0,alpha: 1.0)
context.fill(pageRect)
context.saveGState()
// Handle rotation
context.translateBy(x: 0.0, y: pageRect.size.height)
context.scaleBy(x: 1.0, y: -1.0)
context.concatenate(firstPage.getDrawingTransform(.mediaBox, rect: pageRect, rotate: 0, preserveAspectRatio: true))
context.drawPDFPage(firstPage)
context.restoreGState()
let image:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}
There are as you may already know 2 ways of rendering PDF's:
UIWebView
Quartz Rendering
The Other answers at the time of writing this have focused on Quartz. There are a number of good reasons for this mostly performance related but in my opinion using Quartz is worth it. I would recommend reading this thread to get a better idea of the pro's and cons.
There is apparently an excellent newish api for Quartz based pdf rendering here
ofc you could present the pdf via UIWebView and render the thumbs using quartz.
There is also a bit of confussion around thumbs, for people new quartz pdf magic, it might seem that after some searching there are apis that support thumbs abut you should check if the support is for embedded thumbs only, many PDF's don't have these.
Another option is to create the thumbs yourself (using quartz) and there are plenty of examples of this around the net including the two answers above. However If you are targeting iOS 4 or above I would strongly recommend using blocks. (Also graphics contexts are thread safe since 4).
I found a significant performance increase when I generated thumbs with blocks.
What I have done in the past is:
Have a ViewController for your
thumbs, it has a scrollview that has
a content size appropriate for all
your pages. Insert Placeholder
ImageViews into is if you like.
On document load, kick off a thumb
generator in the background (see code
below)
The code below calls a method drawImageView that takes the index of the page, grabs the image from the disk and puts it into the scroll view
If your feeling really motivated you can implement a render scope on the thumb scrollView (only rendering the thumbs you need to - something you should be doing for the pdf's anyway)
Dont forget to delete the thumbs when your done, unless you want to cache..
#define THUMB_SIZE 100,144
-(void)generateThumbsWithGCD
{
thumbQueue = dispatch_queue_create("thumbQueue", 0);//thumbQueue = dispatch_queue_t
NSFileManager *fm = [NSFileManager defaultManager];
//good idea to check for previous thumb cache with NSFileManager here
CGSize thumbSize = CGSizeMake(THUMB_SIZE);
__block CGPDFPageRef myPageRef;
NSString *reqSysVer = #"4.0";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
//need to handle ios versions < 4
if ([currSysVer compare:reqSysVer options:NSNumericSearch] == NSOrderedAscending) {NSLog(#"UIKIT MULTITHREADING NOT SUPPORTED!");return;}//thread/api saftey
dispatch_async(thumbQueue, ^{
for (i=1; i<=_maxPages; i++) {
//check if worker is valid (class member bool) for cancelations
myPageRef=[[PDFDocument sharedPDFDocument]getPageData:i];//pdfdocument is a singleton class
if(!myPageRef)return;
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString* imageName = [NSString stringWithFormat:#"%#thumb%i.png",documentName,i];
NSString* fullPathToFile = [thumbDocPath stringByAppendingPathComponent:imageName];
if(![fm fileExistsAtPath:fullPathToFile]){
//NSLog(#"Not there");
UIGraphicsBeginImageContext(thumbSize);//thread Safe in iOs4
CGContextRef context = UIGraphicsGetCurrentContext();//thread Safe in iOs4
CGContextTranslateCTM(context, 0, 144);
CGContextScaleCTM(context, 0.15, -0.15);
CGContextDrawPDFPage (context, myPageRef);
UIImage * render = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData* imageData= UIImagePNGRepresentation(render);
if(imageData){
NSLog(#"WROTE TO:%#",fullPathToFile);
if(![imageData writeToFile:fullPathToFile atomically:NO])NSLog(#"ERROR: Thumb Didnt Save"); //COMMENT OUT TO DISABLE WRITE
}
}
else NSLog(#"Allready There! %#",fullPathToFile);
//update progress on thumb viewController if you wish here
[pool release];
dispatch_sync(dispatch_get_main_queue(), ^{
[self drawImageView:i];
});
}
});
dispatch_release(thumbQueue);
}
I come up with a solution that uses CoreGraphics and Swift 3.0. It's highly inspired by the one presented Alexandre. In my opinion my approach results in more 'Swifty' code. Also, my solution fixes a couple of problems with scaling and orientation of resulting image.
Note that my code uses AVMakeRect(aspectRatio:, insideRect:) and requires import of AVFoundation.
//pages numbering starts from 1.
func generate(size: CGSize, page: Int) -> UIImage? {
guard let document = CGPDFDocument(url as CFURL), let page = document.page(at: page) else { return nil }
let originalPageRect: CGRect = page.getBoxRect(.mediaBox)
var targetPageRect = AVMakeRect(aspectRatio: originalPageRect.size, insideRect: CGRect(origin: CGPoint.zero, size: size))
targetPageRect.origin = CGPoint.zero
UIGraphicsBeginImageContextWithOptions(targetPageRect.size, true, 0)
defer { UIGraphicsEndImageContext() }
guard let context = UIGraphicsGetCurrentContext() else { return nil }
context.setFillColor(gray: 1.0, alpha: 1.0)
context.fill(targetPageRect)
context.saveGState()
context.translateBy(x: 0.0, y: targetPageRect.height)
context.scaleBy(x: 1.0, y: -1.0)
context.concatenate(page.getDrawingTransform(.mediaBox, rect: targetPageRect, rotate: 0, preserveAspectRatio: true))
context.drawPDFPage(page)
context.restoreGState()
return context.makeImage().flatMap() { UIImage(cgImage: $0, scale: UIScreen.main.scale, orientation: .up) }
}
I just rewrote the Objective-C code to Swift. Maybe anyone else can use it:
func getThumbnail(url:NSURL, pageNumber:Int) -> UIImage {
var pdf:CGPDFDocumentRef = CGPDFDocumentCreateWithURL(url as CFURLRef);
var firstPage = CGPDFDocumentGetPage(pdf, pageNumber)
var width:CGFloat = 240.0;
var pageRect:CGRect = CGPDFPageGetBoxRect(firstPage, kCGPDFMediaBox);
var pdfScale:CGFloat = width/pageRect.size.width;
pageRect.size = CGSizeMake(pageRect.size.width*pdfScale, pageRect.size.height*pdfScale);
pageRect.origin = CGPointZero;
UIGraphicsBeginImageContext(pageRect.size);
var context:CGContextRef = UIGraphicsGetCurrentContext();
// White BG
CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0);
CGContextFillRect(context,pageRect);
CGContextSaveGState(context);
// ***********
// Next 3 lines makes the rotations so that the page look in the right direction
// ***********
CGContextTranslateCTM(context, 0.0, pageRect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextConcatCTM(context, CGPDFPageGetDrawingTransform(firstPage, kCGPDFMediaBox, pageRect, 0, true));
CGContextDrawPDFPage(context, firstPage);
CGContextRestoreGState(context);
var thm:UIImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return thm;
}

Efficient thumbnail creation for PDF files like iBooks

How is iBooks able to create PDF page thumbnails so fast on first load? I tried using CGContext functions to draw the page and then resize it to get a thumbnail. But this approach takes way to long. Is there an efficient way to get thumbnails of PDF pages?
Thanks in advance,
Anupam
First get all your PDF files Path in an array[here ie:pdfs].Then if you want to show all these PDF thumbnails in UICollectionView,just pass the index obtained from the collection view Delegate Method "CellForRowAtIndexPath" to the following,
-(UIImage *)GeneratingIcon:(int)index
{
NSURL* pdfFileUrl = [NSURL fileURLWithPath:[pdfs objectAtIndex:index]];
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((__bridge CFURLRef)pdfFileUrl);
CGPDFPageRef page;
CGRect aRect = CGRectMake(0, 0, 102, 141); // thumbnail size
UIGraphicsBeginImageContext(aRect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
UIImage* IconImage;
CGContextSaveGState(context);
CGContextTranslateCTM(context, 0.0, aRect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSetGrayFillColor(context, 1.0, 1.0);
CGContextFillRect(context, aRect);
// Grab the first PDF page
page = CGPDFDocumentGetPage(pdf, 1);
CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform(page, kCGPDFMediaBox, aRect, 0, true);
// And apply the transform.
CGContextConcatCTM(context, pdfTransform);
CGContextDrawPDFPage(context, page);
// Create the new UIImage from the context
IconImage = UIGraphicsGetImageFromCurrentImageContext();
CGContextRestoreGState(context);
UIGraphicsEndImageContext();
CGPDFDocumentRelease(pdf);
return IconImage;
}
Hope this would be fast enough to create thumbnail images for the PDF.
Disclaimer: I have not checked if this is faster or not.
There are some built in methods in ImageIO that are specialized in creating thumbnails. These methods should be optimized for creating thumbnails. You would need to add ImageIO.framework to your project and #import <ImageIO/ImageIO.h> in your code.
// Get PDF-data
NSData *pdfData = [NSData dataWithContentsOfURL:myFileURL];
// Get reference to the source
// NOTE: You are responsible for releasing the created image source
CGImageSourceRef imageSourceRef = CGImageSourceCreateWithData((__bridge CFDataRef)pdfData, NULL);
// Configure how to create the thumbnail
// NOTE: You should change the thumbnail size depending on how large thumbnails you need.
// 512 pixels is probably way too big. Smaller sizes will be faster.
NSDictionary* thumbnailOptions =
#{(id)kCGImageSourceCreateThumbnailWithTransform: (id)kCFBooleanTrue,
(id)kCGImageSourceCreateThumbnailFromImageIfAbsent: (id)kCFBooleanTrue,
(id)kCGImageSourceThumbnailMaxPixelSize: #512}; // no more than 512 px wide or high
// Create thumbnail
// NOTE: You are responsible for releasing the created image
CGImageRef imageRef =
CGImageSourceCreateThumbnailAtIndex(imageSourceRef,
0, // index 0 of the source
(__bridge CFDictionaryRef)thumbnailOptions);
// Do something with the thumbnail ...
// Release the imageRef and imageSourceRef
CGImageRelease (imageRef);
CFRelease(imageSourceRef);