将PDF转换为UIImage

12
func drawOnPDF(path: String)
{
    // Get existing Pdf reference
    let pdf = CGPDFDocumentCreateWithURL(NSURL(fileURLWithPath: path))

    // Get page count of pdf, so we can loop through pages and draw them accordingly
    let pageCount = CGPDFDocumentGetNumberOfPages(pdf);

    // Write to file
    UIGraphicsBeginPDFContextToFile(path, CGRectZero, nil)

    // Write to data
//        var data = NSMutableData()
//        UIGraphicsBeginPDFContextToData(data, CGRectZero, nil)

    for index in 1...pageCount {
        let page = CGPDFDocumentGetPage(pdf, index)
        let pageFrame = CGPDFPageGetBoxRect(page, kCGPDFMediaBox)

        UIGraphicsBeginPDFPageWithInfo(pageFrame, nil)

        var ctx = UIGraphicsGetCurrentContext()

        // Draw existing page
        CGContextSaveGState(ctx);
        CGContextScaleCTM(ctx, 1, -1);
        CGContextTranslateCTM(ctx, 0, -pageFrame.size.height);
        CGContextDrawPDFPage(ctx, page);
        CGContextRestoreGState(ctx);

        // Draw image on top of page
        var image = UIImage(named: "signature3")
        image?.drawInRect(CGRectMake(100, 100, 100, 100))
        // Draw red box on top of page
        //UIColor.redColor().set()
        //UIRectFill(CGRectMake(20, 20, 100, 100));
    }

    UIGraphicsEndPDFContext()
}

我的问题是如何将PDF转换为图像,然后在视图中打开图像并左右、上下滑动。

5个回答

14

Swift 3:

func convertPDFPageToImage(page:Int) {

    let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let filePath = documentsURL.appendingPathComponent("pathLocation").path

    do {

        let pdfdata = try NSData(contentsOfFile: filePath, options: NSData.ReadingOptions.init(rawValue: 0))

        let pdfData = pdfdata as CFData
        let provider:CGDataProvider = CGDataProvider(data: pdfData)!
        let pdfDoc:CGPDFDocument = CGPDFDocument(provider)!
        pageCount = pdfDoc.numberOfPages;
        let pdfPage:CGPDFPage = pdfDoc.page(at: page)!
        var pageRect:CGRect = pdfPage.getBoxRect(.mediaBox)
        pageRect.size = CGSize(width:pageRect.size.width, height:pageRect.size.height)

        print("\(pageRect.width) by \(pageRect.height)")

        UIGraphicsBeginImageContext(pageRect.size)
        let context:CGContext = UIGraphicsGetCurrentContext()!
        context.saveGState()
        context.translateBy(x: 0.0, y: pageRect.size.height)
        context.scaleBy(x: 1.0, y: -1.0)
        context.concatenate(pdfPage.getDrawingTransform(.mediaBox, rect: pageRect, rotate: 0, preserveAspectRatio: true))
        context.drawPDFPage(pdfPage)
        context.restoreGState()
        let pdfImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()            

        self.imageView.image = pdfImage

    }
    catch {

    }

}

嗨,Blain。我尝试运行你的代码,但是 do {} 块没有执行。你知道为什么吗? - Subin K Kuriakose
3
你可以在https://www.hackingwithswift.com/example-code/core-graphics/how-to-render-a-pdf-to-an-image找到类似的答案(它是一个更好的可重用函数,以URL作为输入和UIImage作为返回)。 - Samuël

6

我为PDF页面转换成UIImage找到了解决方案。这段代码将PDF页面转换为UIImage并保存在图像文档目录中。将PDF下载和页面计数分开,以便逐个页面转换为图像。

    func drawOnPDF(path: String)
    {
        var urlstr: NSURL = NSURL.fileURLWithPath(path)!
        var pdf: CGPDFDocumentRef = CGPDFDocumentCreateWithURL(urlstr)
        var page: CGPDFPageRef;
        var frame: CGRect = CGRectMake(0, 0, 100, 200)
        var pageCount: Int = CGPDFDocumentGetNumberOfPages(pdf);
        for (var i = 0; i < pageCount; i++)
        {
            var mypage: CGPDFPageRef = CGPDFDocumentGetPage(pdf, i+1)
            frame = CGPDFPageGetBoxRect(mypage, kCGPDFMediaBox)
            UIGraphicsBeginImageContext(CGSizeMake(600, 600*(frame.size.height/frame.size.width)))
            var ctx: CGContextRef = UIGraphicsGetCurrentContext()
            CGContextSaveGState(ctx)
            CGContextTranslateCTM(ctx, 0.0, frame.size.height)
            CGContextScaleCTM(ctx, 1.0, -1.0)
            CGContextSetGrayFillColor(ctx, 1.0, 1.0)
            CGContextFillRect(ctx, frame)
            page = CGPDFDocumentGetPage(pdf, i + 1)
            var pdfTransform: CGAffineTransform = CGPDFPageGetDrawingTransform(page, kCGPDFMediaBox, frame, 0, true)
            CGContextConcatCTM(ctx, pdfTransform);
            CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh)
            CGContextSetRenderingIntent(ctx, kCGRenderingIntentDefault)
            CGContextDrawPDFPage(ctx, page)
            var thumbnailImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()
            CGContextRestoreGState(ctx)
            var documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).last! as! String 
            documentsPath = documentsPath.stringByAppendingFormat("/Page%d.png", i+1)
            UIGraphicsEndImageContext()
            imagedata = UIImagePNGRepresentation(thumbnailImage)
            imagedata.writeToFile(documentsPath, atomically: true)
            array.addObject(documentsPath)
        }
        let dirPath = array.objectAtIndex(0) as? String
        let image    = UIImage(contentsOfFile: dirPath!)
        NSUserDefaults.standardUserDefaults().setObject(array, forKey: "Array")
        println("\(array)")
    }

Swift中将PDF转换为图像的好方法.. :) @bhargav - InsaneCat

4
所有这些解决方案都将单个pdf页面转换为一个UIImage。以下是我在将多个页面的pdf转换为单个图像时的发现。
func drawPDFfromURL(url: URL) -> UIImage? {
        guard let document = CGPDFDocument(url as CFURL) else { return nil }

        var width: CGFloat = 0
        var height: CGFloat = 0
        
        // calculating overall page size
        for index in 1...document.numberOfPages {
            print("index: \(index)")
            if let page = document.page(at: index) {
                let pageRect = page.getBoxRect(.mediaBox)
                width = max(width, pageRect.width)
                height = height + pageRect.height
            }
        }

        // now creating the image
        let renderer = UIGraphicsImageRenderer(size: CGSize(width: width, height: height))

        let image = renderer.image { (ctx) in
            ctx.cgContext.scaleBy(x: 1.0, y: -1.0)
            for index in 1...document.numberOfPages {
                
                if let page = document.page(at: index) {
                    let pageRect = page.getBoxRect(.mediaBox)
                    ctx.cgContext.translateBy(x: 0.0, y: -pageRect.height)
                    ctx.cgContext.drawPDFPage(page)
                }
            }
            
            ctx.cgContext.scaleBy(x: 1.0, y: -1.0)
        }
        return image
    }

3
我找到了一个很酷的解决方案。 引用自这里: https://www.hackingwithswift.com/example-code/core-graphics/how-to-render-a-pdf-to-an-image
func drawPDFfromURL(url: URL) -> UIImage? {
    guard let document = CGPDFDocument(url as CFURL) else { return nil }
    guard let page = document.page(at: 1) else { return nil }

    let pageRect = page.getBoxRect(.mediaBox)
    let renderer = UIGraphicsImageRenderer(size: pageRect.size)
    let img = renderer.image { ctx in
        UIColor.white.set()
        ctx.fill(pageRect)

        ctx.cgContext.translateBy(x: 0.0, y: pageRect.size.height)
        ctx.cgContext.scaleBy(x: 1.0, y: -1.0)

        ctx.cgContext.drawPDFPage(page)
    }

    return img
}

在我的iOS14.2上,Swift 5完美运行。 - FrugalResolution

1
使用PDFKit:
1)获取PDF路径
2)访问要转换为图像的PDF页面:
let pdfPage = PDFDocument(url: pdfPath)?.page(at: 0)

3)获取PDF页面大小:

let pageSize = pdfPage.bounds(for: .mediaBox).size

3) 使用缩略图功能将页面转换为图像:

let pdfImage = pdfPage?.thumbnail(of: pageSize, for: .mediaBox)

你从哪里获取pdfPagebounds呢? - Piakkaa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接