iOS – 通过渲染丢失质量从UIView生成PDF

我用下面的方法从UIView生成PDF。 他们都创buildPDF但失去质量:

方法1:

@implementation UIView(PDFWritingAdditions) - (void)renderInPDFFile:(NSString*)path { CGRect mediaBox = self.bounds; CGContextRef ctx = CGPDFContextCreateWithURL((__bridge_retained CFURLRef)[NSURL fileURLWithPath:path], &mediaBox, NULL); CGPDFPageRef page; CGContextDrawPDFPage(ctx, page); CGPDFContextBeginPage(ctx, NULL); // Also tried following commented lines but no luck // CGContextSetFlatness(ctx, 0.1); // CGContextSetAllowsAntialiasing(ctx, YES); // CGContextSetAllowsFontSmoothing(ctx, YES); // CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh); CGContextScaleCTM(ctx, 1, -1); CGContextTranslateCTM(ctx, 0, -mediaBox.size.height); [self.layer renderInContext:ctx]; CGPDFContextEndPage(ctx); CFRelease(ctx); } @end 

方法2:

 - (void)createPDFfromUIView:(UIView*)aView saveToDocumentsWithFileName:(NSString*)aFilename { // Creates a mutable data object for updating with binary data, like a byte array NSMutableData *pdfData = [NSMutableData data]; // Points the pdf converter to the mutable data object and to the UIView to be converted UIGraphicsBeginPDFContextToData(pdfData, aView.bounds, nil); UIGraphicsBeginPDFPage(); CGContextRef pdfContext = UIGraphicsGetCurrentContext(); // draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData [aView.layer renderInContext:pdfContext]; // remove PDF rendering context UIGraphicsEndPDFContext(); // Retrieves the document directories from the iOS device NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES); NSString* documentDirectory = [documentDirectories objectAtIndex:0]; NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:aFilename]; // instructs the mutable data object to write its context to a file on disk [pdfData writeToFile:documentDirectoryFilename atomically:YES]; NSLog(@"documentDirectoryFileName: %@",documentDirectoryFilename); } 

我想我可能会错过一些pdf上下文的设置,不确定。 此外,我用UIView创buildPNG图像与以下方法是完全相同的质量:

 - (UIImage *)imageFromView:(UIView *)view { UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0); [view.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage * img = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); // Retrieves the document directories from the iOS device NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES); NSString* documentDirectory = [documentDirectories objectAtIndex:0]; NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:@"pdf.png"]; // instructs the mutable data object to write its context to a file on disk [UIImagePNGRepresentation(img) writeToFile:documentDirectoryFilename atomically:YES]; NSLog(@"documentDirectoryFileName: %@",documentDirectoryFilename); return img; } 

有人可以看到我做错了什么? 谢谢。

这是使用视网膜显示器吗? 这可能是一个contentsScale的东西。 看看这个SOpost

编辑好的,现在你已经张贴之前和之后的照片,我看到你想要的发票UIView被渲染为很好,高质量,可打印的vector数据在您的PDF。

我很确定[CALayer renderInContext]总是产生栅格数据,所以你可能更好的手动构buildPDF。 如果您正在谈论税务发票,您是否真的希望布局随着下一次iOS更新而改变?

不过,你可以看看这个答案 ,它不情愿地build议使用UIView作为你的PDF版面的模板系统。

看看您的示例图像,我不确定您的期望是否正确…您的预览窗口部分放大,而您正在绘制一个位图图像到您的PDF – 所以当你放大时,你会看到“锯齿边缘”如果您查看实际大小(从预览或Cmd-0的视图菜单),那么您应该看到一个或多或less相同的图像到您的屏幕截图。

然而,你真正想要做的不只是渲染你的位图UIView到PDF上下文中,而是直接将CoreGraphics绘制和布局到PDF上下文中。 查看本教程http://www.raywenderlich.com/6818/how-to-create-a-pdf-with-quartz-2d-in-ios-5-tutorial-part-2为例。 这将确保您的文字和线条放大时保持清晰,并确保打印在纸上的高品质产品。 Quartz2Dvectorgraphics是你的朋友在这里,因为你永远不会得到一个高品质的位图,至less不是没有创build一个巨大的PDF文件…

编辑好吧,这不完全相同的问题,但我认为解决scheme将是类似的

我认为这是来自PDF的高品质UIImage的一个骗局

在那里看到我的答案:

https://stackoverflow.com/a/14152516/210171

当你问PDF的页面大小,你得到一个72 PPI的宽度/高度。 您可以尝试创build使用缩放转换放大的上下文。 例如,如果要以300 dpi的分辨率进行渲染,请添加一个比例变换,以便按比例缩放300.0/72.0

如果导出为TIFF,则可以封装生成图像的最终PPI(300)。