How to generate thumbnails from a PDF document with iPhone SDK?

后端 未结 6 838
予麋鹿
予麋鹿 2020-12-24 08:46

I have read the Apple PDF documentation with Quartz.

But I do not know how to generate the thumbnails from a PDF document...

Any idea/sample code ?

相关标签:
6条回答
  • 2020-12-24 08:58

    Swift 4 Version of Prine's Answer

    func thumbnailFromPdf(withUrl url:URL, pageNumber:Int, width: CGFloat = 240) -> UIImage? {
        guard let pdf = CGPDFDocument(url as CFURL),
            let page = pdf.page(at: pageNumber)
            else {
                return nil
        }
    
        var pageRect = page.getBoxRect(.mediaBox)
        let pdfScale = width / pageRect.size.width
        pageRect.size = CGSize(width: pageRect.size.width*pdfScale, height: pageRect.size.height*pdfScale)
        pageRect.origin = .zero
    
        UIGraphicsBeginImageContext(pageRect.size)
        let context = UIGraphicsGetCurrentContext()!
    
        // White BG
        context.setFillColor(UIColor.white.cgColor)
        context.fill(pageRect)
        context.saveGState()
    
        // Next 3 lines makes the rotations so that the page look in the right direction
        context.translateBy(x: 0.0, y: pageRect.size.height)
        context.scaleBy(x: 1.0, y: -1.0)
        context.concatenate(page.getDrawingTransform(.mediaBox, rect: pageRect, rotate: 0, preserveAspectRatio: true))
    
        context.drawPDFPage(page)
        context.restoreGState()
    
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
    
    0 讨论(0)
  • 2020-12-24 09:02

    Here is my sample code.

    NSURL* pdfFileUrl = [NSURL fileURLWithPath:finalPath];
    CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfFileUrl);
    CGPDFPageRef page;
    
    CGRect aRect = CGRectMake(0, 0, 70, 100); // thumbnail size
    UIGraphicsBeginImageContext(aRect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    UIImage* thumbnailImage;
    
    
    NSUInteger totalNum = CGPDFDocumentGetNumberOfPages(pdf);
    
    for(int i = 0; i < totalNum; i++ ) {
    
    
        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, i + 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
        thumbnailImage = UIGraphicsGetImageFromCurrentImageContext();
    
        //Use thumbnailImage (e.g. drawing, saving it to a file, etc)
    
        CGContextRestoreGState(context);
    
    }
    
    
    UIGraphicsEndImageContext();    
    CGPDFDocumentRelease(pdf);
    
    0 讨论(0)
  • 2020-12-24 09:02

    From iOS 11 you can use PDFKit.

    import PDFKit
    
    func generatePdfThumbnail(of thumbnailSize: CGSize , for documentUrl: URL, atPage pageIndex: Int) -> UIImage? {
        let pdfDocument = PDFDocument(url: documentUrl)
        let pdfDocumentPage = pdfDocument?.page(at: pageIndex)
        return pdfDocumentPage?.thumbnail(of: thumbnailSize, for: PDFDisplayBox.trimBox)
    }
    

    Call it:

    let thumbnailSize = CGSize(width: 100, height: 100)
    
    let thumbnail = generatePdfThumbnail(of: thumbnailSize, for: url, atPage: 0)
    
    0 讨论(0)
  • 2020-12-24 09:14

    Starting with iOS 11 where PDFKit framework became available, you can get a thumbnail as simply as:

    import PDFKit
    
    func pdfThumbnail(url: URL, width: CGFloat = 240) -> UIImage? {
      guard let data = try? Data(contentsOf: url),
      let page = PDFDocument(data: data)?.page(at: 0) else {
        return nil
      }
    
      let pageSize = page.bounds(for: .mediaBox)
      let pdfScale = width / pageSize.width
    
      // Apply if you're displaying the thumbnail on screen
      let scale = UIScreen.main.scale * pdfScale
      let screenSize = CGSize(width: pageSize.width * scale, 
                              height: pageSize.height * scale)
    
      return page.thumbnail(of: screenSize, for: .mediaBox)
    } 
    
    0 讨论(0)
  • 2020-12-24 09:16

    In the meantime I have created a library which does support PDF, Images and Videos for creating thumbnails. Maybe someone else can use it:

    https://github.com/prine/ROThumbnailGenerator

    Solution in Swift. Just pass the NSURL to the PDF and the page number you want to retrieve as UIImage:

    func getThumbnail(url:NSURL, pageNumber:Int) -> UIImage {
    
        var pdf:CGPDFDocumentRef = CGPDFDocumentCreateWithURL(url as CFURLRef);
    
        var firstPage = CGPDFDocumentGetPage(pdf, pageNumber)
    
        // Change the width of the thumbnail here
        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;
    }
    
    0 讨论(0)
  • 2020-12-24 09:16

    For objective-c

    CGRect pageSize = [[self.pdfView.document pageAtIndex:0] boundsForBox:kPDFDisplayBoxMediaBox];
    CGFloat pdfScale = [UIScreen mainScreen].bounds.size.width /pageSize.size.width;
    CGFloat scale = [UIScreen mainScreen].scale * pdfScale;
    UIImage thumbnailImage = [[self.pdfView.document pageAtIndex:0] thumbnailOfSize:CGSizeMake(pageSize.size.width *scale, pageSize.size.height *scale) forBox:kPDFDisplayBoxMediaBox];
    
    0 讨论(0)
提交回复
热议问题