2012-06-06 21 views

回答

6

以下方法將從PDF文件構建縮略圖。這是RetinaDisplay意識到的,所以縮略圖應該在這些設備上特別清晰。

- (UIImage *)buildThumbnailImage 
{ 
    BOOL hasRetinaDisplay = FALSE; // by default 
    CGFloat pixelsPerPoint = 1.0; // by default (pixelsPerPoint is just the "scale" property of the screen) 

    if ([UIScreen instancesRespondToSelector:@selector(scale)]) // the "scale" property is only present in iOS 4.0 and later 
    { 
    // we are running iOS 4.0 or later, so we may be on a Retina display; we need to check further... 
    if ((pixelsPerPoint = [[UIScreen mainScreen] scale]) == 1.0) 
     hasRetinaDisplay = FALSE; 
    else 
     hasRetinaDisplay = TRUE; 
    } 
    else 
    { 
    // we are NOT running iOS 4.0 or later, so we can be sure that we are NOT on a Retina display 
    pixelsPerPoint = 1.0; 
    hasRetinaDisplay = FALSE; 
    } 

    size_t imageWidth = 320; // width of thumbnail in points 
    size_t imageHeight = 460; // height of thumbnail in points 

    if (hasRetinaDisplay) 
    { 
    imageWidth *= pixelsPerPoint; 
    imageHeight *= pixelsPerPoint; 
    } 

    size_t bytesPerPixel = 4; // RGBA 
    size_t bitsPerComponent = 8; 
    size_t bytesPerRow = bytesPerPixel * imageWidth; 

    void *bitmapData = malloc(imageWidth * imageHeight * bytesPerPixel); 

    // in the event that we were unable to mallocate the heap memory for the bitmap, 
    // we just abort and preemptively return nil: 
    if (bitmapData == NULL) 
    return nil; 

    // remember to zero the buffer before handing it off to the bitmap context: 
    bzero(bitmapData, imageWidth * imageHeight * bytesPerPixel); 

    CGContextRef theContext = CGBitmapContextCreate(bitmapData, imageWidth, imageHeight, bitsPerComponent, bytesPerRow, 
                CGColorSpaceCreateDeviceRGB(), kCGImageAlphaPremultipliedLast); 

    CGPDFDocumentRef pdfDocument = MyGetPDFDocumentRef(); // NOTE: you will need to modify this line to supply the CGPDFDocumentRef for your file here... 
    CGPDFPageRef pdfPage = CGPDFDocumentGetPage(pdfDocument, 1); // get the first page for your thumbnail 

    CGAffineTransform shrinkingTransform = 
    CGPDFPageGetDrawingTransform(pdfPage, kCGPDFMediaBox, CGRectMake(0, 0, imageWidth, imageHeight), 0, YES); 

    CGContextConcatCTM(theContext, shrinkingTransform); 

    CGContextDrawPDFPage(theContext, pdfPage); // draw the pdfPage into the bitmap context 
    CGPDFDocumentRelease(pdfDocument); 

    // 
    // create the CGImageRef (and thence the UIImage) from the context (with its bitmap of the pdf page): 
    // 
    CGImageRef theCGImageRef = CGBitmapContextCreateImage(theContext); 
    free(CGBitmapContextGetData(theContext)); // this frees the bitmapData we malloc'ed earlier 
    CGContextRelease(theContext); 

    UIImage *theUIImage; 

    // CAUTION: the method imageWithCGImage:scale:orientation: only exists on iOS 4.0 or later!!! 
    if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) 
    { 
    theUIImage = [UIImage imageWithCGImage:theCGImageRef scale:pixelsPerPoint orientation:UIImageOrientationUp]; 
    } 
    else 
    { 
    theUIImage = [UIImage imageWithCGImage:theCGImageRef]; 
    } 

    CFRelease(theCGImageRef); 
    return theUIImage; 
} 

您需要提供與您的PDF文件相對應的CGPDFDocumentRef,如下所示。 (這一個假設檢驗.pdf文件在應用程序的主束存在。)

CGPDFDocumentRef MyGetPDFDocumentRef() 
{ 
    NSString *inputPDFFile = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"test.pdf"]; 
    const char *inputPDFFileAsCString = [inputPDFFile cStringUsingEncoding:NSASCIIStringEncoding]; 
    //NSLog(@"expecting pdf file to exist at this pathname: \"%s\"", inputPDFFileAsCString); 

    CFStringRef path = CFStringCreateWithCString(NULL, inputPDFFileAsCString, kCFStringEncodingUTF8); 

    CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, 0); 
    CFRelease (path); 

    CGPDFDocumentRef document = CGPDFDocumentCreateWithURL(url); 
    CFRelease(url); 

    if (CGPDFDocumentGetNumberOfPages(document) == 0) 
    { 
    printf("Warning: No pages in pdf file \"%s\" or pdf file does not exist at this path\n", inputPDFFileAsCString); 
    return NULL; 
    } 

    return document; 
} 

最後,你可以在一個的UIImageView顯示縮略圖,就像這樣:

UIImageView *thumbnailImageView = [[UIImageView alloc] initWithImage:[self buildThumbnailImage]]; 

    [self.view addSubview:thumbnailImageView]; 
+0

謝謝大家!我會盡快嘗試!我第一次使用stackoverflow,這簡直太神奇了! – iconso

6

由於部分一個我正在研究的項目,我修改了inwit的代碼,以便在調用中使用變量。我想我會後他們在這裏幫助的人誰是尋找一個類似的解決方案:

打電話給他們:

//Assume all your PDFs you want to create thumbnails for are in an array. This method saves the paths to all PDFs in your main bundle as NSStrings. 
_pdfs = [[NSBundle mainBundle] pathsForResourcesOfType:@"pdf" inDirectory:nil]; 

//To be called in the cellForItemAtIndexPath method or a similar method where you want to create a thumbnail for the image: 
NSString *loc = [_pdfs objectAtIndex:indexPath.row];  
UIImage *cellImage = [self buildThumbnailImage:MyGetPDFDocumentRef(loc)]; 

的方法和C函數:

- (UIImage *)buildThumbnailImage:(CGPDFDocumentRef)pdfDocument 
{ 
    BOOL hasRetinaDisplay = FALSE; // by default 
    CGFloat pixelsPerPoint = 1.0; // by default (pixelsPerPoint is just the "scale" property of the screen) 

    if ([UIScreen instancesRespondToSelector:@selector(scale)]) // the "scale" property is only present in iOS 4.0 and later 
    { 
     // we are running iOS 4.0 or later, so we may be on a Retina display; we need to check further... 
     if ((pixelsPerPoint = [[UIScreen mainScreen] scale]) == 1.0) 
      hasRetinaDisplay = FALSE; 
     else 
      hasRetinaDisplay = TRUE; 
    } 
    else 
    { 
     // we are NOT running iOS 4.0 or later, so we can be sure that we are NOT on a Retina display 
     pixelsPerPoint = 1.0; 
     hasRetinaDisplay = FALSE; 
    } 

    size_t imageWidth = 320; // width of thumbnail in points 
    size_t imageHeight = 460; // height of thumbnail in points 

    if (hasRetinaDisplay) 
    { 
     imageWidth *= pixelsPerPoint; 
     imageHeight *= pixelsPerPoint; 
    } 

    size_t bytesPerPixel = 4; // RGBA 
    size_t bitsPerComponent = 8; 
    size_t bytesPerRow = bytesPerPixel * imageWidth; 

    void *bitmapData = malloc(imageWidth * imageHeight * bytesPerPixel); 

    // in the event that we were unable to mallocate the heap memory for the bitmap, 
    // we just abort and preemptively return nil: 
    if (bitmapData == NULL) 
     return nil; 

    // remember to zero the buffer before handing it off to the bitmap context: 
    bzero(bitmapData, imageWidth * imageHeight * bytesPerPixel); 

    CGContextRef theContext = CGBitmapContextCreate(bitmapData, imageWidth, imageHeight, bitsPerComponent, bytesPerRow, 
                CGColorSpaceCreateDeviceRGB(), kCGImageAlphaPremultipliedLast); 

    //CGPDFDocumentRef pdfDocument = MyGetPDFDocumentRef(); // NOTE: you will need to modify this line to supply the CGPDFDocumentRef for your file here... 
    CGPDFPageRef pdfPage = CGPDFDocumentGetPage(pdfDocument, 1); // get the first page for your thumbnail 

    CGAffineTransform shrinkingTransform = 
    CGPDFPageGetDrawingTransform(pdfPage, kCGPDFMediaBox, CGRectMake(0, 0, imageWidth, imageHeight), 0, YES); 

    CGContextConcatCTM(theContext, shrinkingTransform); 

    CGContextDrawPDFPage(theContext, pdfPage); // draw the pdfPage into the bitmap context 
    CGPDFDocumentRelease(pdfDocument); 

    // 
    // create the CGImageRef (and thence the UIImage) from the context (with its bitmap of the pdf page): 
    // 
    CGImageRef theCGImageRef = CGBitmapContextCreateImage(theContext); 
    free(CGBitmapContextGetData(theContext)); // this frees the bitmapData we malloc'ed earlier 
    CGContextRelease(theContext); 

    UIImage *theUIImage; 

    // CAUTION: the method imageWithCGImage:scale:orientation: only exists on iOS 4.0 or later!!! 
    if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) 
    { 
     theUIImage = [UIImage imageWithCGImage:theCGImageRef scale:pixelsPerPoint orientation:UIImageOrientationUp]; 
    } 
    else 
    { 
     theUIImage = [UIImage imageWithCGImage:theCGImageRef]; 
    } 

    CFRelease(theCGImageRef); 
    return theUIImage; 
} 


CGPDFDocumentRef MyGetPDFDocumentRef(NSString *inputPDFFile) 
{ 
    //NSString *inputPDFFile = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"test.pdf"]; 

    const char *inputPDFFileAsCString = [inputPDFFile cStringUsingEncoding:NSASCIIStringEncoding]; 
    //NSLog(@"expecting pdf file to exist at this pathname: \"%s\"", inputPDFFileAsCString); 

    CFStringRef path = CFStringCreateWithCString(NULL, inputPDFFileAsCString, kCFStringEncodingUTF8); 

    CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, 0); 
    CFRelease (path); 

    CGPDFDocumentRef document = CGPDFDocumentCreateWithURL(url); 
    CFRelease(url); 

    if (CGPDFDocumentGetNumberOfPages(document) == 0) 
    { 
     printf("Warning: No pages in pdf file \"%s\" or pdf file does not exist at this path\n", inputPDFFileAsCString); 
     return NULL; 
    } 

    return document; 
} 
+0

我們可以得到文件,XLS,CSV等第一個文件快照。我們可以得到那些 – kiri

+0

在上面的代碼中的PDF預覽使用核心圖形呈現PDF的第一頁(https://developer.apple。 COM /庫/ MAC /文檔/ GraphicsImaging /參考/ CGPDFPage /)。 Core Graphics不提供用於呈現Office文檔類型的類似功能,因此要實現文檔預覽,您需要實現自己的呈現代碼來創建預覽。此方法不能輕易修改您的目的。 – jonschneider

相關問題