Create pdf thumbnail on iphone

I am new to programming iPhone Objective-c. I have an application in which I display PDF in my UIWebView successfully, but now I want to create a thumbnail of my PDF. My PDF file is stored in my resources folder.

So give me the code, how can I show a thumbnail of my PDF. My code is for displaying a PDF, which is used as a 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]; } 
+6
source share
5 answers

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; } 
+23
source

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 } 
+2
source

As you already know, there are two ways to render PDF:

  • UIWebView
  • Quartz rendering

Other answers at the time of this writing have focused on Quartz. There are several good reasons for this, mainly related to work, but in my opinion, the use of quartz is worth it. I would recommend reading this topic to better understand the pros and cons.

There seems to be an excellent new qui-based PDF rendering api here

ofc you can submit a PDF via UIWebView and make thumbs with quartz.

There are also a few misunderstandings regarding the thumbs, for people creating a new quartz PDF mockup, it might seem that after some searches there are apis that support the thumbs, you should check if support supports the built-in preview only, many PDFs do not have these .

Another option is to create thumbs (using quartz), and there are many examples of this on the net, including the two answers above. However, if you are targeting iOS 4 or higher, I highly recommend using blocks. (Also graphical contexts are thread safe with 4).

I found a significant increase in performance when I generated thumbs with blocks.

What I have done in the past is:

  • You have a ViewController for your preview, it has a scrollview that has a content size that fits all of your pages. Embed ImageViews placeholder in if you like.

  • When loading a document, release the thumb generator in the background (see code below)

  • In the code below, the drawImageView method is drawImageView , which takes the index of the page, grabs the image from disk, and puts it in the scroll view

  • If your feeling is really motivated, you can implement the visualization area on the scrollView of your thumb (just to make the thumbs you need - something you should do for pdf anyway)

  • Remember to remove the thumbs at runtime if you do not 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); } 

code>

+1
source

I just rewrote Objective-C code in Swift. Maybe someone 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; } 
+1
source

I came up with a solution that uses CoreGraphics and Swift 3.0. He is very inspired to introduce Alexander. In my opinion, my approach leads to more "Swifty" code. In addition, my solution fixes several problems with scaling and orientation of the resulting image.

Please note that my code uses AVMakeRect(aspectRatio:, insideRect:) and requires importing 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) } } 
0
source

Source: https://habr.com/ru/post/885884/


All Articles