2010-11-05 61 views
10

我們正在使用UIWebViews顯示PDF內容。理想情況下,我希望能夠在UITableView中顯示縮略圖,而不會同時加載許多不同的UIWebViews ......它們足夠慢加載一個文檔 - 不要介意10+!如何以編程方式生成iPhone SDK的PDF縮略圖?

有沒有人有關於如何去做這件事的任何提示?

我想過屏幕捕獲使用UIDocumentInteractionControllerUIWebView加載的文檔,但這意味着它們都必須在顯示錶之前縮略圖。

回答

11

Apple直接在CoreGraphics級別提供了大量方法來繪製PDF內容。據我所知,在UIKit級別都沒有整齊地包裝起來,所以在這一點上它可能不適合你的項目,特別是如果你不太適應C級。但是,相關函數是CGContextDrawPDFPage;,按照正常的方式有其他方法可以從數據源創建PDF引用,然後從PDF獲取頁面引用。然後,您需要處理縮放並轉換爲您需要的視圖,並且需要警告您需要執行水平翻轉操作,因爲PDF(和OS X)使用左下角作爲原點,而iOS使用左上角。示例代碼,從我的頭頂:

UIGraphicsBeginImageContext(thumbnailSize); 
CGPDFDocumentRef pdfRef = CGPDFDocumentCreateWithProvider((CGDataProviderRef)instanceOfNSDataWithPDFInside); 
CGPDFPageRef pageRef = CGPDFDocumentGetPage(pdfRef, 1); // get the first page 

CGContextRef contextRef = UIGraphicsGetCurrentContext(); 

// ignore issues of transforming here; depends on exactly what you want and 
// involves a whole bunch of normal CoreGraphics stuff that is nothing to do 
// with PDFs 
CGContextDrawPDFPage(contextRef, pageRef); 

UIImage *imageToReturn = UIGraphicsGetImageFromCurrentImageContext(); 

// clean up 
UIGraphicsEndImageContext(); 
CGPDFDocumentRelease(pdfRef); 

return imageToReturn; 

在猜測,你可能會想使用CGPDFPageGetBoxRect(pageRef, kCGPDFCropBox)獲得頁面的裁剪框,然後制定出如何縮放/動議,以適應您的圖片大小。

你的目的

可能更容易上CALayer(見QA 1703)的-renderInContext:方法 - 讓一個屏幕截圖是UIGetScreenImage的老手段,但從來沒有真正官方的API,並似乎暫時只允許因的RedLaser的意外審批。通過QA中的代碼,您可以自行設置從其他視圖獲取UIImage,而不必在屏幕上顯示該視圖。哪些可能解決您的屏幕捕獲問題?儘管這意味着您只能支持OS 4.x。

無論是哪種情況,PDF都不會很快得出。您可能需要填充表格,然後在後臺線程上繪製縮略圖,並在可用時向上推動縮略圖。你不能在後臺線程上安全地使用UIKit對象,但所有的東西都是安全的。

12

以下是考慮轉換的示例代碼。 :)

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

嗨alones迅速3的方法,我用你的代碼來獲取PDF縮略圖。看起來像CGContextConcatCTM(上下文,pdfTransform)行產生一個內存瓶頸,我發現如果我離開這條線,那就沒關係。但我不能離開它,因爲我需要這個適當的縮略圖。你有什麼想法可以改進嗎? Thx btw ... – aslisabanci 2011-08-10 15:11:15

+0

這一個適合我......上面的一個我不知道爲什麼,但它產生了一個虛擬或垃圾縮圖...謝謝... – Underdog 2011-08-31 14:17:42

+0

doc的說UIGraphicsGetImageFromCurrentImageContext()是不是線程安全的 – 2012-05-15 18:16:59

1

這裏是產生一個UIImage縮略圖PDF頁面

static func getThumbnailForPDF(_ urlString:String, pageNumber:Int) -> UIImage? { 
    let bundle = Bundle.main 
    let path = bundle.path(forResource: urlString, ofType: "pdf") 
    let pdfURL = URL(fileURLWithPath: path!) 

    let pdf = CGPDFDocument(pdfURL as CFURL)! 
    let page = pdf.page(at: pageNumber)! 
    let rect = CGRect(x: 0, y: 0, width: 100.0, height: 70.0) //Image size here 

    UIGraphicsBeginImageContext(rect.size) 
    let context = UIGraphicsGetCurrentContext()! 

    context.saveGState() 
    context.translateBy(x: 0, y: rect.height) 
    context.scaleBy(x: 1.0, y: -1.0) 
    context.setFillColor(gray: 1.0, alpha: 1.0) 
    context.fill(rect) 


    let pdfTransform = page.getDrawingTransform(CGPDFBox.mediaBox, rect: rect, rotate: 0, preserveAspectRatio: true) 
    context.concatenate(pdfTransform) 
    context.drawPDFPage(page) 

    let thumbImage = UIGraphicsGetImageFromCurrentImageContext() 
    context.restoreGState() 

    UIGraphicsEndImageContext() 

    return thumbImage 
} 
+0

嗨,Emil,你晚了約7年 - 但感謝沒有讓這個問題繼續存在面對同一問題的任何人;-) – 2017-04-29 18:17:27

相關問題