1

我正在尝试使用 Quartz 框架解析 PDF 文档,并将 Apple 文档中的代码片段复制并粘贴到我的源代码中。不幸的是,它不检索任何数据。它只是遍历页面,将当前页面的数量记录到控制台并在最后崩溃。您对代码有什么问题有任何想法吗?

static void op_MP (CGPDFScannerRef s, void *info)
{
    const char *name;

    if (!CGPDFScannerPopName(s, &name))
        return;

    printf("MP /%s\n", name);
}

static void op_DP (CGPDFScannerRef s, void *info)
{
    const char *name;

    if (!CGPDFScannerPopName(s, &name))
        return;

     NSLog(@"DP /%s\n", name);
}

static void op_BMC (CGPDFScannerRef s, void *info)
{
    const char *name;

    if (!CGPDFScannerPopName(s, &name))
        return;

    NSLog(@"BMC /%s\n", name);
}

static void op_BDC (CGPDFScannerRef s, void *info)
{
    const char *name;

    if (!CGPDFScannerPopName(s, &name))
        return;
     NSLog(@"BDC /%s\n", name);
}

static void op_EMC (CGPDFScannerRef s, void *info)
{
    const char *name;

    if (!CGPDFScannerPopName(s, &name))
        return;

     NSLog(@"EMC /%s\n", name);
}

static void op_TJ (CGPDFScannerRef s, void *info)
{
    const char *name;

    if (!CGPDFScannerPopName(s, &name))
        return;

     NSLog(@"TJ /%s\n", name);
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    CGPDFDocumentRef myDocument;
    NSString *urlAddress = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"pdf"];
    NSURL *fileUrl = [NSURL fileURLWithPath:urlAddress];
    CFURLRef url = (__bridge CFURLRef)fileUrl;
    myDocument = CGPDFDocumentCreateWithURL(url);

    CFRelease (url);

    if (myDocument == NULL) {// 2
        NSLog(@"can't open `%@'.", fileUrl);
     }
    if (!CGPDFDocumentIsUnlocked (myDocument)) {// 4
         CGPDFDocumentRelease(myDocument);
    }
    else if (CGPDFDocumentGetNumberOfPages(myDocument) == 0) {// 5
        CGPDFDocumentRelease(myDocument);
    }
    else {
        CGPDFOperatorTableRef myTable;
        myTable = CGPDFOperatorTableCreate();

        CGPDFOperatorTableSetCallback (myTable, "MP", &op_MP);
        CGPDFOperatorTableSetCallback (myTable, "DP", &op_DP);
        CGPDFOperatorTableSetCallback (myTable, "BMC", &op_BMC);
        CGPDFOperatorTableSetCallback (myTable, "BDC", &op_BDC);
        CGPDFOperatorTableSetCallback (myTable, "EMC", &op_EMC);
        CGPDFOperatorTableSetCallback (myTable, "Tj", &op_TJ);

        int k;
        CGPDFPageRef myPage;
        CGPDFScannerRef myScanner;
        CGPDFContentStreamRef myContentStream;

        int numOfPages = CGPDFDocumentGetNumberOfPages (myDocument);// 1
        for (k = 0; k < numOfPages; k++) {
            myPage = CGPDFDocumentGetPage (myDocument, k + 1 );// 2
            myContentStream = CGPDFContentStreamCreateWithPage (myPage);// 3
            myScanner = CGPDFScannerCreate (myContentStream, myTable, NULL);// 4
            CGPDFScannerScan (myScanner);// 5
            CGPDFPageRelease (myPage);// 6
            CGPDFScannerRelease (myScanner);// 7
            CGPDFContentStreamRelease (myContentStream);// 8
            NSLog(@"processed page %i",k);
        }
        CGPDFOperatorTableRelease(myTable);
        CGPDFDocumentRelease(myDocument);
    }

    return YES;
}
4

3 回答 3

1

我没有运行代码,但您的页面内容中可能不存在前 5 个运算符。还有一些有名称操作数,一些没有任何操作数(例如 EMC)。Tj 运算符也有一个字符串操作数,而不是名称。
删除所有弹出名称方法并仅保留日志记录,您可能会得到一些输出。然后查看 PDF 规范以查看每个运算符的确切操作数并相应地更新您的代码。

于 2013-08-16T20:08:01.337 回答
0

虽然我无法为您的示例代码崩溃提供解决方案,但上次我们需要这样做,我们的解析器基于 PDFKitten。

https://github.com/KurtCode/PDFKitten

如果您对解析代码感兴趣,有趣的东西位于 Scanner.m 中:

https://github.com/KurtCode/PDFKitten/blob/master/PDFKitten/Scanner.m

鉴于 PDF 解析的复杂性,我建议以这个库为基础并从那里移动。如果您需要在截止日期前完成完善的实现,那么 PSPDFKit 可能是最完善(但价格昂贵)的软件包。

于 2013-08-16T20:06:52.483 回答
0

这是关于CFRelease(url). 删除它,它会好起来的。

“(__bridge T) op 将操作数转换为目标类型 T。如果 T 是可保留对象指针类型,则 op 必须具有不可保留指针类型。”

于 2015-01-14T22:01:15.720 回答