iphone - 使用 Quartz 在 iOS 上获取 PDF 超链接

标签 iphone ipad pdf quartz-graphics

我花了一整天的时间尝试从 iPad 应用程序中的 PDF 中获取超链接元数据。 CGPDF* API 是一场真正的噩梦,我在网上找到的关于这一切的唯一信息是我必须寻找“Annots”字典,但我在 PDF 中找不到它。

我什至使用了旧的 Voyeur Xcode sample检查我的测试 PDF 文件,但没有这个“Annots”字典的踪迹...

你知道,这是我在每个 PDF 阅读器上看到的功能 - 同样的问题有 been asked multiple times这里没有真正实用的答案。我通常从不直接要求示例代码,但显然这次我真的需要它...有人可以使用示例代码吗?

更新:我刚刚意识到完成我的 PDF 测试的人只是插入了一个 URL 作为文本,而不是真正的注释。他尝试添加注释,我的代码现在可以工作了...但这不是我需要的,所以看来我必须分析文本并搜索 URL。但这是另一个故事了......

更新 2:所以我终于想出了一些工作代码。我将其发布在这里,希望对某人有所帮助。它假设 PDF 文档实际上包含注释。

for(int i=0; i<pageCount; i++) {
    CGPDFPageRef page = CGPDFDocumentGetPage(doc, i+1);

    CGPDFDictionaryRef pageDictionary = CGPDFPageGetDictionary(page);

    CGPDFArrayRef outputArray;
    if(!CGPDFDictionaryGetArray(pageDictionary, "Annots", &outputArray)) {
        return;
    }

    int arrayCount = CGPDFArrayGetCount( outputArray );
    if(!arrayCount) {
        continue;
    }

    for( int j = 0; j < arrayCount; ++j ) {
        CGPDFObjectRef aDictObj;
        if(!CGPDFArrayGetObject(outputArray, j, &aDictObj)) {
            return;
        }

        CGPDFDictionaryRef annotDict;
        if(!CGPDFObjectGetValue(aDictObj, kCGPDFObjectTypeDictionary, &annotDict)) {
            return;
        }

        CGPDFDictionaryRef aDict;
        if(!CGPDFDictionaryGetDictionary(annotDict, "A", &aDict)) {
            return;
        }

        CGPDFStringRef uriStringRef;
        if(!CGPDFDictionaryGetString(aDict, "URI", &uriStringRef)) {
            return;
        }

        CGPDFArrayRef rectArray;
        if(!CGPDFDictionaryGetArray(annotDict, "Rect", &rectArray)) {
            return;
        }

        int arrayCount = CGPDFArrayGetCount( rectArray );
        CGPDFReal coords[4];
        for( int k = 0; k < arrayCount; ++k ) {
            CGPDFObjectRef rectObj;
            if(!CGPDFArrayGetObject(rectArray, k, &rectObj)) {
                return;
            }

            CGPDFReal coord;
            if(!CGPDFObjectGetValue(rectObj, kCGPDFObjectTypeReal, &coord)) {
                return;
            }

            coords[k] = coord;
        }               

        char *uriString = (char *)CGPDFStringGetBytePtr(uriStringRef);

        NSString *uri = [NSString stringWithCString:uriString encoding:NSUTF8StringEncoding];
        CGRect rect = CGRectMake(coords[0],coords[1],coords[2],coords[3]);

        CGPDFInteger pageRotate = 0;
        CGPDFDictionaryGetInteger( pageDictionary, "Rotate", &pageRotate ); 
        CGRect pageRect = CGRectIntegral( CGPDFPageGetBoxRect( page, kCGPDFMediaBox ));
        if( pageRotate == 90 || pageRotate == 270 ) {
            CGFloat temp = pageRect.size.width;
            pageRect.size.width = pageRect.size.height;
            pageRect.size.height = temp;
        }

        rect.size.width -= rect.origin.x;
        rect.size.height -= rect.origin.y;

        CGAffineTransform trans = CGAffineTransformIdentity;
        trans = CGAffineTransformTranslate(trans, 0, pageRect.size.height);
        trans = CGAffineTransformScale(trans, 1.0, -1.0);

        rect = CGRectApplyAffineTransform(rect, trans);

        // do whatever you need with the coordinates.
        // e.g. you could create a button and put it on top of your page
        // and use it to open the URL with UIApplication's openURL
    }
}

最佳答案

这是至少获取每个页面的注释 CGPDFDictionary 的基本思想。之后,您应该能够在 Adob​​e PDF 规范的帮助下找到答案。

1.) 获取 CGPDFDocumentRef。

2.) 获取每个页面。

3.) 在每个页面上,使用 CGPDFDictionaryGetArray(pageDictionary, "Annots", &outputArray)其中 pageDictionary 是表示 CGPDFPage 的 CGPDFDictionary,outputArray 是用于存储该页面的 Annots 数组的变量 (CGPDFArrayRef)。

关于iphone - 使用 Quartz 在 iOS 上获取 PDF 超链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4080373/

相关文章:

pdf - 如何使用 XSL-FO 在 PDF 中添加分页符?

iphone - iOS警报中的下拉菜单

iphone - UIToolbar 多行文本

iphone - 如何替换 UIWebView 中的 SwipeGestureRecognizer 操作

iphone - 为 iPhone/iPad 编写单元测试的最佳方法是什么?

objective-c - 以编程方式选择 uitableview 行

iphone - Xcode如何决定先加载哪个xib?我该如何改变它?

ios - IBOutlet 不来

php - GhostScript PDF 合并(丢失可编辑字段)

javascript - 如何更改 base64 应用程序/pdf 文件名?