如何在阅读PDF时从这些回调中获取值?

时间:2017-05-30 12:31:16

标签: ios swift cgpdf

我正在尝试阅读PDF文件。回调下面还会打印消息,但我无法从PDF中获取信息。

    let pdfBundlePath = Bundle.main.path(forResource: "sample", ofType: "pdf")
    let pdfURL = URL.init(fileURLWithPath: pdfBundlePath!)
    let pdf = CGPDFDocument(pdfURL as CFURL)        

    let operatorTableRef = CGPDFOperatorTableCreate()

    CGPDFOperatorTableSetCallback(operatorTableRef!, "BT") { (scanner, info) in
        print("Begin text object")
    }
    CGPDFOperatorTableSetCallback(operatorTableRef!, "ET") { (scanner, info) in
        print("End text object")
    }
    CGPDFOperatorTableSetCallback(operatorTableRef!, "Tf") { (scanner, info) in
        print("Select font")
    }
    CGPDFOperatorTableSetCallback(operatorTableRef!, "Tj") { (scanner, info) in
        print("Show text")
    }
    CGPDFOperatorTableSetCallback(operatorTableRef!, "TJ") { (scanner, info) in
        print("Show text, allowing individual glyph positioning")
    }

        let page = pdf!.page(at: 1)
        let stream = CGPDFContentStreamCreateWithPage(page!)
        let scanner = CGPDFScannerCreate(stream, operatorTableRef, nil)
        CGPDFScannerScan(scanner)
        CGPDFScannerRelease(scanner)
        CGPDFContentStreamRelease(stream)

输出:

Begin text object
Select font
Show text, allowing individual glyph positioning
End text object

// the same output for at least 10 or more times.

但我不确定如何从中获取实际的字符串?任何建议都将不胜感激。

1 个答案:

答案 0 :(得分:2)

我有pdf"你好,世界" text(从TextEdit导出为pdf创建)

此回调函数

CGPDFOperatorTableSetCallback(operatorTableRef!, "TJ") { (scanner, info) in
    print("Show text, allowing individual glyph positioning")
    var pa: CGPDFArrayRef?
    withUnsafeMutablePointer(to: &pa, { (ppa) -> () in
        let r = CGPDFScannerPopArray(scanner, ppa)
        print("TJ", r)
        if r {
            let count = CGPDFArrayGetCount(ppa.pointee!)
            var j = 0
            for i in 0..<count {
                var str: CGPDFStringRef?
                let r = CGPDFArrayGetString(ppa.pointee!, i, &str)
                if r {
                    let string = String(cString: CGPDFStringGetBytePtr(str!)!)
                    print(string, i, j)
                    j += 1
                }
            }
        }
    })
}

打印我

Show text, allowing individual glyph positioning
TJ true
h 0 0
e 2 1
l 4 2
l 6 3
o 8 4
, 10 5
  12 6
w 14 7
o 16 8
rl 18 9
d 20 10

我认为它表明,获得字符串是可能的:-),至少对于拉丁字母。

对于Tj运算符,回调函数可以像

一样简单
CGPDFOperatorTableSetCallback(operatorTableRef!, "Tj") { (scanner, info) in
        print("Show text")
        var text: CGPDFStringRef?
        withUnsafeMutablePointer(to: &text, { (p) -> () in
            let r = CGPDFScannerPopString(scanner, p)
            if r {
                let string = String(cString: CGPDFStringGetBytePtr(p.pointee!)!)
                print(string)
            }
        })
    }

警告! 为了正确显示所有字符,它是必要的使用字体信息,但这是一个不同的故事。对于拉丁字符,此解决方案应该按原样运行。

能够提取&#39;所有字符串,所有文本显示操作符必须实现

<强>更新 因为 PDFKit在两个苹果平台上都可用(来自iOS11)我建议将其用于文本提取。这个过程非常简单