【问题标题】:Image of the first pdf page ios sdk第一个pdf页面ios sdk的图像
【发布时间】:2012-06-10 18:08:10
【问题描述】:

你知道如何将 pdf 文件的第一页保存到 UIImageView 中吗? 我必须为 pdf 创建预览。 你有什么想法吗?

感谢您的帮助 尼科

【问题讨论】:

    标签: iphone objective-c ios pdf uiimage


    【解决方案1】:

    以下方法将从 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,如下所示。 (这个假设文件 test.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];
    

    【讨论】:

    • 谢谢大家!我会尽快尝试!第一次用stackoverflow,简直太神奇了!
    【解决方案2】:

    作为我正在进行的项目的一部分,我修改了 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;
    }
    

    【讨论】:

    • 我们可以获取 doc、Xls、CSV 等的第一个文件快照吗?我们可以获取这些
    • 上述代码中的PDF预览是使用Core Graphics渲染PDF的第一页(developer.apple.com/library/mac/documentation/GraphicsImaging/…)。 Core Graphics 不提供类似的渲染办公室文档类型的功能,因此要实现文档预览,您需要实现自己的渲染代码来创建预览。此方法不能轻易修改为您的目的。
    【解决方案3】:

    UIViews的截图有几种方式:

    看这里 http://www.icodeblog.com/2009/07/27/1188/

    也看这里: How Do I Take a Screen Shot of a UIView?

    这可能很麻烦,但您可以在 UIWebview 中打开 PDF,使用上面指向 UIImageView 的链接之一中的代码截取第一页的屏幕截图。然后关闭 PDF。

    【讨论】:

      【解决方案4】:

      这就是你要找的吗? -http://ipdfdev.com/2011/03/28/convert-a-pdf-page-to-image-on-the-iphone-and-ipad/。输出是一个 UIImage,所以你应该能够在你的 UIImageView 中显示它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-26
        • 2012-12-22
        • 1970-01-01
        相关资源
        最近更新 更多