最近有很多关于绘制PDF的问题.
是的,你可以很容易地使用a来渲染PDF,UIWebView但这不能提供你期望从一个好的PDF查看器中获得的性能和功能.
您可以将PDF页面绘制到CALayer或UIImage.Apple甚至有示例代码来展示如何在Zoomable UIScrollview中绘制大型PDF
但同样的问题不断出现.
UIImage方法:
UIImage不是光学尺度,也不是图层方法.UIImages从PDFcontext
限制/防止使用它来创建一个实时渲染的新的缩放的水平.CATiledLayer方法:
CALayer:可以看到单个图块渲染(即使使用tileSize调整)CALayers 不能提前准备(在屏幕外呈现).一般来说,PDF查看器的内存也很重要.甚至监视苹果可缩放PDF示例的内存使用情况.
在我目前的项目中,我正在开发一个PDF查看器,并UIImage在一个单独的线程中呈现一个页面(这里也是问题!)并在比例为x1时呈现它.CATiledLayer一旦比例> 1,渲染就会开始.iBooks采用了类似的双重拍摄方法,就好像你滚动页面一样,你可以看到页面的低分辨率版本只有不到一秒钟,然后出现一个清晰的版本.
我在页面的每一侧渲染2页焦点,以便PDF图像准备好在它开始绘制之前掩盖图层.当页面离焦点页面+2页时,它们会被再次销毁.
有没有人有任何见解,无论多么小或明显改善Drawing PDF的性能/内存处理?或者这里讨论的任何其他问题?
编辑:一些提示(信用 - 卢克麦克尼斯,VdesmedT,马特加拉格尔,约翰):
尽可能将所有媒体保存到磁盘.
如果在TiledLayers上渲染,请使用更大的tileSizes
init经常使用带占位符对象的数组,另外另一种设计方法就是这个
请注意,图像渲染速度比a快 CGPDFPageRef
使用NSOperations或GCD和块提前准备页面.
CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh); CGContextSetRenderingIntent(ctx, kCGRenderingIntentDefault);之前调用CGContextDrawPDFPage以减少绘制时的内存使用量
使用docRef初始化你NSOperations是个坏主意(内存),将docRef包装成单例.
取消不必要NSOperations当你可以,特别是如果他们将使用记忆,但要小心打开上下文!
回收页面对象并销毁未使用的视图
一旦您不需要它们,请立即关闭所有打开的上下文
接收内存警告释放并重新加载DocRef和任何页面缓存
其他PDF功能:
获取链接的目标(从/Dest数组中获取页码)
搜索(和这里)(不适用于所有PDF(有些只显示奇怪的字符,我想这是一个编码问题,但我不确定)-Credit BrainFeeder)
CALayer和离屏渲染 - 渲染下一页以便快速/平滑显示
文档
示例项目
UIScrollView,,CATiledLayerUIScrollView,CATiledViewVde*_*edT 103
我使用近似相同的方法构建这种应用程序,除了:
UIImage而是在缩放为1时在图层中绘制图像.当发出内存警告时,这些图块将自动释放.每当用户开始缩放时,我CGPDFPage都会使用适当的CTM 获取并渲染它.代码- (void)drawLayer: (CALayer*)layer inContext: (CGContextRef) context如下:
CGAffineTransform currentCTM = CGContextGetCTM(context);
if (currentCTM.a == 1.0 && baseImage) {
//Calculate ideal scale
CGFloat scaleForWidth = baseImage.size.width/self.bounds.size.width;
CGFloat scaleForHeight = baseImage.size.height/self.bounds.size.height;
CGFloat imageScaleFactor = MAX(scaleForWidth, scaleForHeight);
CGSize imageSize = CGSizeMake(baseImage.size.width/imageScaleFactor, baseImage.size.height/imageScaleFactor);
CGRect imageRect = CGRectMake((self.bounds.size.width-imageSize.width)/2, (self.bounds.size.height-imageSize.height)/2, imageSize.width, imageSize.height);
CGContextDrawImage(context, imageRect, [baseImage CGImage]);
} else {
@synchronized(issue) {
CGPDFPageRef pdfPage = CGPDFDocumentGetPage(issue.pdfDoc, pageIndex+1);
pdfToPageTransform = CGPDFPageGetDrawingTransform(pdfPage, kCGPDFMediaBox, layer.bounds, 0, true);
CGContextConcatCTM(context, pdfToPageTransform);
CGContextDrawPDFPage(context, pdfPage);
}
}
Run Code Online (Sandbox Code Playgroud)
问题是包含的对象CGPDFDocumentRef.我同步我访问pdfDoc属性的部分,因为我释放它并在接收memoryWarnings时重新创建它.似乎CGPDFDocumentRef对象做了一些内部缓存,我没有找到如何摆脱.
Jos*_*non 66
对于简单有效的PDF查看器,当您只需要有限的功能时,您现在可以(iOS 4.0+)使用QuickLook框架:
首先,你需要链接QuickLook.framework和#import
<QuickLook/QuickLook.h>;
之后,在任何一个viewDidLoad或任何延迟初始化方法中:
QLPreviewController *previewController = [[QLPreviewController alloc] init];
previewController.dataSource = self;
previewController.delegate = self;
previewController.currentPreviewItemIndex = indexPath.row;
[self presentModalViewController:previewController animated:YES];
[previewController release];
Run Code Online (Sandbox Code Playgroud)
从iOS 11开始,您可以使用名为PDFKit的本机框架来显示和操作PDF.
导入PDFKit后,您应该PDFView使用本地或远程URL 初始化a 并在视图中显示它.
if let url = Bundle.main.url(forResource: "example", withExtension: "pdf") {
let pdfView = PDFView(frame: view.frame)
pdfView.document = PDFDocument(url: url)
view.addSubview(pdfView)
}
Run Code Online (Sandbox Code Playgroud)
在Apple Developer文档中阅读有关PDFKit的更多信息.
| 归档时间: |
|
| 查看次数: |
100487 次 |
| 最近记录: |