pt2*_*ph8 55 pdf iphone quartz-graphics ipad
我花了一整天时间尝试从我的iPad应用程序中获取PDF中的超链接元数据.CGPDF*API是一个真正的噩梦,我在网上发现的关于这一切的唯一信息是我必须寻找一个"Annots"字典,但我在我的PDF中找不到它.
我甚至使用旧的Voyeur Xcode样本来检查我的测试PDF文件,但没有这个"Annots"字典的痕迹......
要知道,这是一个功能,我在每一个PDF阅读器看-这个同样的问题已经被 问 多 时间在这里没有真正的实际的答案.我通常不会直接询问示例代码,但显然这次我真的需要它...任何人都有这个工作,可能有示例代码?
更新:我刚刚意识到已经完成我的测试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
}
}
Run Code Online (Sandbox Code Playgroud)
Jes*_*her 15
继承人至少为每个页面获取annots CGPDFDictionary的基本思想.之后,您应该能够在Adobe的PDF规范的帮助下弄清楚它.
1.)获取CGPDFDocumentRef.
2.)获取每一页.
3.)在每个页面上,使用CGPDFDictionaryGetArray(pageDictionary, "Annots", &outputArray)pageDictionary是表示CGPDFPage的CGPDFDictionary,outputArray是用于存储该页面的Annots数组的变量(CGPDFArrayRef).
小智 9
伟大的代码,但我在我的项目中遇到一些麻烦.它正确地获取了所有URL,但是当我点击它时没有任何反应.这是我的代码,我必须稍微修改你的代码才能使用我的项目).有什么遗失:
- (void) renderPageAtIndex:(NSUInteger)index inContext:(CGContextRef)ctx {
//CGPDFPageRef page = CGPDFDocumentGetPage(pdf, index+1);
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, index+1);
CGAffineTransform transform1 = aspectFit(CGPDFPageGetBoxRect(page, kCGPDFMediaBox),
CGContextGetClipBoundingBox(ctx));
CGContextConcatCTM(ctx, transform1);
CGContextDrawPDFPage(ctx, page);
int pageCount = CGPDFDocumentGetNumberOfPages(pdf);
int i = 0;
while (i<pageCount) {
i++;
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 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
NSURL *url = [NSURL URLWithString:uri];
NSLog(@"URL: %@", url);
CGPDFContextSetURLForRect(ctx, (CFURLRef)url, rect);
// CFRelease(url);
}
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢和伟大的工作BrainFeeder!
更新:
对于在你的应用程序中使用leaves项目的任何人来说,这就是我如何使用PDF链接工作(它不完美,因为rect似乎填满整个屏幕,但它是一个开始):
- (void) renderPageAtIndex:(NSUInteger)index inContext:(CGContextRef)ctx {
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, index+1);
CGAffineTransform transform1 = aspectFit(CGPDFPageGetBoxRect(page, kCGPDFMediaBox),
CGContextGetClipBoundingBox(ctx));
CGContextConcatCTM(ctx, transform1);
CGContextDrawPDFPage(ctx, page);
CGPDFPageRef pageAd = CGPDFDocumentGetPage(pdf, index);
CGPDFDictionaryRef pageDictionary = CGPDFPageGetDictionary(pageAd);
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
NSURL *url = [NSURL URLWithString:uri];
NSLog(@"URL: %@", url);
// CGPDFContextSetURLForRect(ctx, (CFURLRef)url, rect);
UIButton *button = [[UIButton alloc] initWithFrame:rect];
[button setTitle:@"LINK" forState:UIControlStateNormal];
[button addTarget:self action:@selector(openLink:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
// CFRelease(url);
}
//}
Run Code Online (Sandbox Code Playgroud)
最终更新 以下是我在我的应用中使用的最终代码.
- (void) renderPageAtIndex:(NSUInteger)index inContext:(CGContextRef)ctx {
//If the view already contains a button control remove it
if ([[self.view subviews] containsObject:button]) {
[button removeFromSuperview];
}
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, index+1);
CGAffineTransform transform1 = aspectFit(CGPDFPageGetBoxRect(page, kCGPDFMediaBox),
CGContextGetClipBoundingBox(ctx));
CGContextConcatCTM(ctx, transform1);
CGContextDrawPDFPage(ctx, page);
CGPDFPageRef pageAd = CGPDFDocumentGetPage(pdf, index);
CGPDFDictionaryRef pageDictionary = CGPDFPageGetDictionary(pageAd);
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, 35, pageRect.size.height+150);
trans = CGAffineTransformScale(trans, 1.15, -1.15);
rect = CGRectApplyAffineTransform(rect, trans);
urlLink = [NSURL URLWithString:uri];
[urlLink retain];
//Create a button to get link actions
button = [[UIButton alloc] initWithFrame:rect];
[button setBackgroundImage:[UIImage imageNamed:@"link_bg.png"] forState:UIControlStateHighlighted];
[button addTarget:self action:@selector(openLink:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
[leavesView reloadData];
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
22438 次 |
| 最近记录: |