我正在使用带有Retina Display 2048x1536分辨率(2倍比例)的全屏iPad从UIViews创建PDF文件。结果文件非常大,我得到6-10 MB的文件,2页相当简单的视图。理想情况下,每个文档我会得到4-5页,但目前的方法会使PDF大小过大。
有没有办法让这样创建的PDF更小?像创建视图的截图,将其转换为JPG,然后将其写入PDF上下文?还是有一些我缺少的质量选择?
以下是从单个视图创建PDF的代码:
+(NSMutableData *)createPDFDatafromUIView:(UIView*)aView
{
// 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();
return pdfData;
}
+(NSString*)createPDFfromUIView:(UIView*)aView saveToFilepath:(NSString*)filepath
{
// Creates a mutable data object for updating with binary data, like a byte array
NSMutableData *pdfData = [AppGraphics createPDFDatafromUIView:aView];
// instructs the mutable data object to write its context to a file on disk
[pdfData writeToFile:filepath atomically:YES];
DLog(@"saving PDF to: %@",filepath);
DLog(@"file exists: %@",[[NSFileManager defaultManager] fileExistsAtPath:filepath]?@"YES":@"NO");
return filepath;
}
这是我用来连接多个PDF的原因
+ (NSString *)joinPDF:(NSArray *)listOfPaths saveToPath:(NSString*)path
{
CFURLRef pdfURLOutput = ( CFURLRef)CFBridgingRetain([NSURL fileURLWithPath:path]);
NSInteger numberOfPages = 0;
// Create the output context
CGContextRef writeContext = CGPDFContextCreateWithURL(pdfURLOutput, NULL, NULL);
for (NSString *source in listOfPaths) {
CFURLRef pdfURL = ( CFURLRef)CFBridgingRetain([[NSURL alloc] initFileURLWithPath:source]);
//file ref
CGPDFDocumentRef pdfRef = CGPDFDocumentCreateWithURL((CFURLRef) pdfURL);
numberOfPages = CGPDFDocumentGetNumberOfPages(pdfRef);
// Loop variables
CGPDFPageRef page;
CGRect mediaBox;
// Read the first PDF and generate the output pages
DLog(@"GENERATING PAGES FROM PDF 1 (%@)...", source);
for (int i=1; i<=numberOfPages; i++) {
page = CGPDFDocumentGetPage(pdfRef, i);
mediaBox = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
CGContextBeginPage(writeContext, &mediaBox);
CGContextDrawPDFPage(writeContext, page);
CGContextEndPage(writeContext);
}
CGPDFDocumentRelease(pdfRef);
CFRelease(pdfURL);
}
CFRelease(pdfURLOutput);
// Finalize the output file
CGPDFContextClose(writeContext);
CGContextRelease(writeContext);
return path;
}
答案 0 :(得分:3)
解决方案确实是在PDF上下文中将图像渲染为JPG。生成的压缩PDF大小较小 - 每页大约300-400kb!
//aView is used for its bounds property
//screenshot is the screenshot of the view within its bounds
//compression quality 0.55 is 380kb/page 0.66 is 450kb/page
+(NSString*)createPDFDataFromUIView:(UIView*)aView withScreenshot:(UIImage*)screenshot compressionQuality:(float)compression writeToFile:(NSString*)filepath
{
//prepare JPEG data for rendering into PDF content
NSData *jpegData = UIImageJPEGRepresentation(screenshot, compression);
CGDataProviderRef dp = CGDataProviderCreateWithCFData((__bridge CFDataRef)jpegData);
CGImageRef cgImage = CGImageCreateWithJPEGDataProvider(dp, NULL, true, kCGRenderingIntentDefault);
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
//we need to change the coordinate system, otherwise the image is drawn upside down
CGContextTranslateCTM(pdfContext, 0, aView.bounds.size.height);
CGContextScaleCTM(pdfContext, 1.0, -1.0);
//this creates pixels within PDF context
CGContextDrawImage(pdfContext, aView.bounds, cgImage);
// remove PDF rendering context
UIGraphicsEndPDFContext();
[pdfData writeToFile:filepath atomically:YES];
//memory cleanup
CGDataProviderRelease(dp);
CGImageRelease(cgImage);
return filepath;
}