使用Quartz在iOS上获取PDF超链接 [英] Get PDF hyperlinks on iOS with Quartz

查看:112
本文介绍了使用Quartz在iOS上获取PDF超链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've spent all day trying to get hyperlinks metadata from PDFs in my iPad application. The CGPDF* APIs are a true nightmare, and the only piece of information I've found on the net about all this is that I have to look for an "Annots" dictionary, but I just can't find it in my PDFs.

我甚至使用过旧的偷窥Xcode示例检查我的测试PDF文件,但没有这个Annots字典的痕迹...

I even used the old Voyeur Xcode sample to inspect my test PDF file, but no trace of this "Annots" dictionary...

你知道,这是我在每个人看到的一个功能PDF阅读器 - 同样的问题有已经 询问 multiple 这里没有真正的实际答案。我通常从不直接询问示例代码,但显然这次我确实需要它......任何人都有这个工作,可能有示例代码?

You know, this is a feature I see on every PDF reader - this same question has been asked multiple times here with no real practical answers. I usually never ask for sample code directly but apparently this time I really need it... anyone got this working, possibly with sample code?

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

Update: I just realized the guy who has done my testing PDF had just inserted an URL as text, and not a real annotation. He tried putting an annotation and my code works now... But that's not what I need, so it seems I'll have to analyze text and search for URLs. But that's another story...

更新2 :所以我终于提出了一些有效的代码。我在这里张贴它,所以希望它能帮助别人。它假定PDF文档实际上包含注释。

Update 2: So I finally came up with some working code. I'm posting it here so hopefully it'll help someone. It assumes the PDF document actually contains annotations.

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
    }
}


推荐答案

以下是至少为每个页面获取annots CGPDFDictionary的基本思路。之后你应该能够在Adobe的PDF规范的帮助下弄明白。

heres the basic idea to get to the annots CGPDFDictionary for each page atleast. after that you should be able to figure it out with help from the PDF spec from Adobe.

1。)获取CGPDFDocumentRef。

1.) get the CGPDFDocumentRef.

2。)获取每个页面。

2.) get each page.

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

3.) on each page, use CGPDFDictionaryGetArray(pageDictionary, "Annots", &outputArray) where pageDictionary is the CGPDFDictionary representing the CGPDFPage, and outputArray is the variable (CGPDFArrayRef) to store the Annots array of that page in.

这篇关于使用Quartz在iOS上获取PDF超链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆