我花了一整天时间尝试从我的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)) { …Run Code Online (Sandbox Code Playgroud) 我想写使用一个简单的PDF查看器CGPDFDocument,基于QuartzDemo.
常见的渲染:
-(void)drawInContext:(CGContextRef)context
{
// PDF page drawing expects a Lower-Left coordinate system,
// so we flip the coordinate system before we start drawing.
CGContextTranslateCTM(context, 0.0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// Grab the first PDF page
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, pageNumber);
// We're about to modify the context CTM to draw the PDF page
// where we want it, so save the graphics state
// in case we want to do more drawing
CGContextSaveGState(context);
// CGPDFPageGetDrawingTransform provides an …Run Code Online (Sandbox Code Playgroud) 在使用Quartz尝试从PDF读取注释两天后,我设法完成并发布了我的代码.
现在我想对另一个常见问题做同样的事情:用Quartz搜索PDF文档.与以前相同的情况,这个问题已被多次询问,几乎没有实际答案.所以我首先需要一些指针,因为我自己还没有实现.
我尝试了什么:
我尝试使用CGPDFScannerScan处理TJ和Tj运算符 - 在某些PDF上返回正确的文本,而在其他文档上它返回大多数随机字母.也许它与文本编码有关?
有人指出应该处理文本块(由BT/ET操作符标记),但我仍然没有设法这样做.有人设法从任何PDF中提取文本吗?
之后,通过将所有文本存储在一起NSMutableString并使用rangeOfString(如果有更好的方式请告诉我),搜索应该很容易.
但那么如何突出结果呢?我知道有一些运算符可以找到字形大小,所以我可以根据这些值来计算得到的矩形,但我已经读了几个小时的规格......这是一个臃肿的混乱,我疯了.有实际解释的人吗?
用户Naveen Thunga发现了PDFKitten,"用于从iOS中提取PDF数据的框架".我只是尝试了演示,它似乎像宣传的那样工作.我将用更多的PDF测试它,并很快发布结果.作为旁注,代码对我来说似乎非常好 - 如果你对这些东西是如何工作感兴趣它非常棒.
这是代码:
https://www.dropbox.com/s/o42wy36x4qhrbpt/PDFScroller.zip
我采用了WWDC 2010 PhotoScroller示例代码,该代码实现了嵌套UIScrollViews用于缩放,内部UIScrollView用于分页,并且换掉了我认为显示多页PDF而不是图像所需的最少量代码.
有用.但是我的iPhone4上的速度很慢,第一页画的时间大约是三秒钟,而我的iPod Touch则更慢.我可以看它画个别瓷砖.这个相同的PDF已经打开得更快,没有可见的平铺图,在CATiledLayer我的替代实现中,它只使用单个CATiledLayer/ UIScrollView和触摸事件来更改页面.我想用这种PhotoScroller技术,非常好.
我用仪器中的CPU Sampler观察它,它似乎不是PDF渲染代码,看起来时间在线程和消息传递中占用.如果有人可以帮助指出这个样本正在做什么来招致开销,我会很感激.
谢谢,
吉姆
更新1:我最初使用了TilingView定义示例代码中的类技术
+ (Class) layerClass {
return [CATiledLayer class];
}
Run Code Online (Sandbox Code Playgroud)
然后- (void)drawRect:(CGRect)rect插入但切换到显CATiledLayer式子类作为第一次尝试,看它是否会产生影响,但它没有,所以我留下代码原样在这里发布.[tiledLayer release];TilingView中也有漏掉的漏洞.
关于pdf解析的另一个问题...请阅读PDF参考版本1.7"5.3.1文本定位运算符",我有点困惑.
我写了一些代码来获得转换矩阵和初始文本位置.
CGPDFOperatorTableSetCallback (table, "MP", &op_MP);//Define marked-content point
CGPDFOperatorTableSetCallback (table, "DP", &op_DP);//Define marked-content point with property list
CGPDFOperatorTableSetCallback (table, "BMC", &op_BMC);//Begin marked-content sequence
CGPDFOperatorTableSetCallback (table, "BDC", &op_BDC);//Begin marked-content sequence with property list
CGPDFOperatorTableSetCallback (table, "EMC", &op_EMC);//End marked-content sequence
//Text State operators
CGPDFOperatorTableSetCallback(table, "Tc", &op_Tc);
CGPDFOperatorTableSetCallback(table, "Tw", &op_Tw);
CGPDFOperatorTableSetCallback(table, "Tz", &op_Tz);
CGPDFOperatorTableSetCallback(table, "TL", &op_TL);
CGPDFOperatorTableSetCallback(table, "Tf", &op_Tf);
CGPDFOperatorTableSetCallback(table, "Tr", &op_Tr);
CGPDFOperatorTableSetCallback(table, "Ts", &op_Ts);
//text showing operators
CGPDFOperatorTableSetCallback(table, "TJ", &op_TJ);
CGPDFOperatorTableSetCallback(table, "Tj", &op_Tj);
CGPDFOperatorTableSetCallback(table, "'", &op_apostrof);
CGPDFOperatorTableSetCallback(table, "\"", &op_double_apostrof);
//text positioning operators …Run Code Online (Sandbox Code Playgroud) 我有一个UIScrollView内容大小足以容纳一些小的UIScrollViews用于缩放viewForZoomingInScrollView的分页,这是一个viewController,它包含一个用于绘制PDF页面的CALayer.这使我能够像ibooks PDF阅读器一样浏览PDF.
绘制PDF(平铺图层)的代码位于:
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx;
Run Code Online (Sandbox Code Playgroud)
只需在可见屏幕上添加"页面"即可自动调用此方法.当我更改页面时,在绘制所有图块之前会有一些延迟,即使已经创建了对象(页面).
我想要做的是在用户滚动到它之前渲染下一页,从而防止可见的平铺效果.但是,我发现如果图层位于屏幕外,将其添加到scrollview中则不会调用drawLayer.
这里有什么想法/常见问题吗?
我试过了:
[viewController.view.layer setNeedsLayout];
[viewController.view.layer setNeedsDisplay];
Run Code Online (Sandbox Code Playgroud)
注意:这是在功能上复制ibooks的事实在完整应用程序的上下文中是无关紧要的.
我是Objective-c iPhone编程的新手.我有一个应用程序,我在UIWebView中成功显示PDF,但现在我想创建我的PDF的缩略图.我的PDF存储在我的资源文件夹中.
所以请给我一些代码,说明如何显示我的PDF缩略图.我的代码用于显示PDF是按钮功能:
-(void)show:(id)sender {
pdfView.autoresizesSubviews = NO;
pdfView.scalesPageToFit=YES;
pdfView.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);
[pdfView setDelegate:self];
NSString *path = [[NSBundle mainBundle] pathForResource:@"com" ofType:@"pdf"];
NSLog(@"Path of res is%@",path);
NSURL *url = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[pdfView loadRequest:request];
}
Run Code Online (Sandbox Code Playgroud) 我正在使用quartz来显示pdf内容,我需要创建一个目录来浏览pdf.从阅读Apple的文档我认为我应该使用CGPDFDocumentGetCatalog,但我找不到任何关于如何在任何地方使用它的例子.有任何想法吗?
更新:仍未找到解决方案.我厌倦了Alex的解决方案,但我得到的输出看起来像这样:
2011-07-27 09:16:19.359 LDS Scriptures App-iPad[624:707] key: Pages
2011-07-27 09:16:19.361 LDS Scriptures App-iPad[624:707] key: Count
2011-07-27 09:16:19.362 LDS Scriptures App-iPad[624:707] pdf integer value: 238
2011-07-27 09:16:19.363 LDS Scriptures App-iPad[624:707] key: Kids
2011-07-27 09:16:19.366 LDS Scriptures App-iPad[624:707] key: Type
2011-07-27 09:16:19.368 LDS Scriptures App-iPad[624:707] key: Outlines
2011-07-27 09:16:19.370 LDS Scriptures App-iPad[624:707] key: Count
2011-07-27 09:16:19.371 LDS Scriptures App-iPad[624:707] pdf integer value: 7
2011-07-27 09:16:19.372 LDS Scriptures App-iPad[624:707] key: First
2011-07-27 09:16:19.374 LDS Scriptures App-iPad[624:707] key: Parent
2011-07-27 09:16:19.375 LDS …Run Code Online (Sandbox Code Playgroud) 我一直在阅读adobe pdf规范,以及用于pdf渲染和解析的apple的quartz 2d文档.我还下载了Voyeur并用它检查了一个本地pdf以查看它的内部数据.此时我可以获取文档目录,然后从那里获取轮廓字典.我可以看到嵌套在轮廓词典词典中的是名为"/ Dest"的节点,其值如下:
G1.1025588等
我想知道是否有一种方法让我使用这些值来获取对页面的引用,使用一些方法来渲染我已经看过github项目,如Reader,以及Apple记录的示例.
PDF处理绝对是一个挑战,所以任何帮助将不胜感激.
当我用Instruments分析我的应用程序时,我发现CGContextDrawPDFPage分配的数据不会立即释放.由于我的程序收到很多"内存警告",我想释放尽可能多的内存,但我不知道如何释放这个内存.
正如您在http://twitpic.com/473e89/full上看到的,它似乎与此代码有关
-(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)ctx{
NSAutoreleasePool * tiledViewPool = [[NSAutoreleasePool alloc] init];
CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0);
CGContextFillRect(ctx, CGContextGetClipBoundingBox(ctx));
CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform([self.superview.superview getPage],kCGPDFMediaBox,tiledLayer.bounds, 0, true);
CGContextSaveGState (ctx);
CGContextTranslateCTM(ctx, 0.0, tiledLayer.bounds.size.height);
CGContextScaleCTM(ctx, 1.0, -1.0);
CGContextConcatCTM (ctx, pdfTransform);
CGContextClipToRect (ctx, CGPDFPageGetBoxRect([self.superview.superview getPage],kCGPDFMediaBox));
CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh);
CGContextSetRenderingIntent(ctx, kCGRenderingIntentDefault);
CGContextDrawPDFPage(ctx,[self.superview.superview getPage]);
CGContextRestoreGState (ctx);
UIGraphicsEndPDFContext();
[tiledViewPool drain];
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试在它周围包装一个AutoReleasePool,但这似乎没有任何影响.屏幕截图是在TiledView(方法所属的视图)被释放后拍摄的.
我希望有人可以帮我减少内存使用量.
iphone ×8
pdf ×7
objective-c ×5
cocoa-touch ×4
ipad ×4
ios ×3
catiledlayer ×2
quartz-2d ×2
2d ×1
calayer ×1
hyperlink ×1
performance ×1
uiscrollview ×1