iOS - 通过渲染丢失质量从UIView生成PDF [英] iOS - Generating PDF from UIView by rendering loses quality

查看:121
本文介绍了iOS - 通过渲染丢失质量从UIView生成PDF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用以下方法从UIView生成PDF。所有这些都创建了PDF但却失去了质量:

I've used the following methods to generate a PDF from a UIView. All of them create the PDF but loses quality:

方法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用以下方法创建png图像,质量完全相同:

I think I may be missing some settings for the pdf context, not sure. Also I've create png image from UIView with following method which is exact same quality:

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

有人能看出我做错了吗?
谢谢。

Can someone see what I'm doing wrong? Thanks.

推荐答案

这是否使用了视网膜显示器?它可能是contentScale的东西。看看这个SO发布

Is this using a retina display? It could be a contentsScale thing. Have a look at this SO post

编辑
好​​了,现在您已经发布了&在图片之后,我看到您希望发票UIView在PDF中呈现为漂亮,高质量,可打印的矢量数据。

EDIT Ok, now that you've posted before & after pics, I see that what you want the invoice UIView to be rendered as nice, high quality, printable vector data in your PDF.

我很确定[ CALayer renderInContext]总是生成栅格数据,因此您最好手动构建PDF。如果你在谈论税收发票,你真的希望布局在下一次iOS更新时改变吗?

I'm pretty sure that [CALayer renderInContext] always produces raster data, so you're probably better off constructing the PDF manually. And if you're talking about tax invoices, do you really want the layout to change with the next iOS update?

但是,你可以查看此答案,不情愿地建议使用UIView作为PDF布局的模板系统。

However, you could look at this answer, which reluctantly suggests using the UIView as a template system for your PDF layout.

这篇关于iOS - 通过渲染丢失质量从UIView生成PDF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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