问题
I want to generate a pdf of UIScrollView whose content size is near about 320*2000. If I use current graphic image context to capture the scroll view layer, then it only captures the visible part of the scroll view not the whole layer of that scroll view.
I am using the below code:
-(void)CreatePdf:(id)sender
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *saveDirectory = [paths objectAtIndex:0];
NSString *saveFileName = @"myPDF.pdf";
[self writePDFAma];
CGRect arect=CGRectMake(0, 0, 768, 1024);
CreatePDFFileAma(arect, nil);
}
-(void) writePDFAma
{
UIImage *image;
NSData *data;
UIAlertView *successAlert;
UIAlertView *failureAlert;
//
NSArray *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// // This should be our documents directory
NSString *saveDiirectory = [documentPath objectAtIndex:0];
// // Our PDF is named 'Example.pdf'
NSString *saveFileName = @"FormImage2.JPG";
// // Create the full path using our saveDirectory and saveFileName
NSString *finalPath = [saveDiirectory stringByAppendingPathComponent:saveFileName];
//NSLog(@"%@",finalPath);
CGSize asize=CGSizeMake(_scrollview.frame.size.width, _scrollview.frame.size.height);
//NSLog(@"%d..%d",mainViewAma.frame.size.width, mainViewAma.frame.size.height);
UIGraphicsBeginImageContext(asize);
[[_scrollview layer] renderInContext:UIGraphicsGetCurrentContext()];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
data = UIImageJPEGRepresentation(image, 1.0);
BOOL catch;
if(!catch){
if ([[NSFileManager defaultManager] createFileAtPath:finalPath contents:data attributes:nil])
{
successAlert = [[UIAlertView alloc] initWithTitle:@"Success" message:@"Doodle was successfully saved to the Photo Library." delegate:self cancelButtonTitle:@"Close" otherButtonTitles:nil];
//[successAlert show];
[successAlert release];
} else {
failureAlert = [[UIAlertView alloc] initWithTitle:@"Failure" message:@"Failed to save doodle to the Photo Library." delegate:self cancelButtonTitle:@"Close" otherButtonTitles:nil];
//[failureAlert show];
[failureAlert release];
}
}
}
void CreatePDFFileAma (CGRect pageRect, const char *filename)
{
// This code block sets up our PDF Context so that we can draw to it
//some code here
CGContextRef pdfContext;
CFURLRef url;
CFMutableDictionaryRef myDictionary = NULL;
NSArray *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// // This should be our documents directory
NSString *saveDirectory = [documentPath objectAtIndex:0];
// // Our PDF is named 'Example.pdf'
//NSString *saveFileName = @"PDFForm2.pdf";
// // Create the full path using our saveDirectory and saveFileName
NSString *finalPath = [saveDirectory stringByAppendingPathComponent:saveFileName];
NSURL * aurl=[[NSURL alloc]initFileURLWithPath:finalPath];
url=(CFURLRef)aurl;
// This dictionary contains extra options mostly for 'signing' the PDF
myDictionary = CFDictionaryCreateMutable(NULL, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(myDictionary, kCGPDFContextTitle, CFSTR("AMA FORM PDF"));
CFDictionarySetValue(myDictionary, kCGPDFContextCreator, CFSTR("My Name2"));
// Create our PDF Context with the CFURL, the CGRect we provide, and the above defined dictionary
pdfContext = CGPDFContextCreateWithURL (url, &pageRect, myDictionary);
// Cleanup our mess
CFRelease(myDictionary);
CFRelease(url);
// Starts our first page
CGContextBeginPage (pdfContext, &pageRect);
// Draws a black rectangle around the page inset by 50 on all sides
CGContextStrokeRect(pdfContext, CGRectMake(50, 50, 768, 1024));
// This code block will create an image that we then draw to the page
CGImageRef image;
CGDataProviderRef provider;
CFURLRef pictureURL;
documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// // This should be our documents directory
saveDirectory = [documentPath objectAtIndex:0];
NSString *saveFileName2 = @"FormImage2.JPG";
// // Create the full path using our saveDirectory and saveFileName
NSString *finalPath2 = [saveDirectory stringByAppendingPathComponent:saveFileName2];
NSURL * aurl2=[[NSURL alloc]initFileURLWithPath:finalPath2];
pictureURL=(CFURLRef)aurl2;
provider = CGDataProviderCreateWithURL (pictureURL);
CFRelease (pictureURL);
image = CGImageCreateWithJPEGDataProvider(provider, NULL, TRUE, kCGRenderingIntentDefault); //DataProvider (, NULL, true, kCGRenderingIntentDefault);
CGDataProviderRelease (provider);
CGContextDrawImage (pdfContext, CGRectMake(0, 0,768, 1024),image);
CGImageRelease (image);
CGContextEndPage (pdfContext);
// We are done with our context now, so we release it
CGContextRelease (pdfContext);
}
回答1:
Heh guys, i prepared some code base using the examples available on net to create PDF from UIScrollView We should be clear about two things
1) number of pages 2) contentsize of scrollview
i have created a scroll view of content size ( 10 * 910). so it has 10 pages.. This is for iPad.
here is the code base
- (void) createPDF
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *directroyPath = nil;
directroyPath = [documentsDirectory stringByAppendingPathComponent:@"PDF"];
NSString *filePath = [directroyPath stringByAppendingPathComponent:@"test.pdf"];
// check for the "PDF" directory
NSError *error;
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
} else {
[[NSFileManager defaultManager] createDirectoryAtPath:directroyPath
withIntermediateDirectories:NO
attributes:nil
error:&error];
}
CGContextRef pdfContext = [self createPDFContext:myScrollView.bounds path:(CFStringRef)filePath];
NSLog(@"PDF Context created");
for (int i = 0 ; i< 10 ; i++)
{
// page 1
CGContextBeginPage (pdfContext,nil);
//turn PDF upsidedown
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformMakeTranslation(0, (i+1) * 910);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
CGContextConcatCTM(pdfContext, transform);
//Draw view into PDF
[myScrollView.layer renderInContext:pdfContext];
CGContextEndPage (pdfContext);
[myScrollView setContentOffset:CGPointMake(0, (i+1) * 910) animated:NO];
}
CGContextRelease (pdfContext);
}
- (CGContextRef) createPDFContext:(CGRect)inMediaBox path:(CFStringRef) path
{
CGContextRef myOutContext = NULL;
CFURLRef url;
url = CFURLCreateWithFileSystemPath (NULL, path,
kCFURLPOSIXPathStyle,
false);
if (url != NULL) {
myOutContext = CGPDFContextCreateWithURL (url,
&inMediaBox,
NULL);
CFRelease(url);
}
return myOutContext;
}
回答2:
I came up with a different solution:
-(NSData*)pdfDataFromTableViewContent{
NSMutableData *pdfData = [NSMutableData data];
//The real size, not only the visible part
CGSize contentSize = self.tableView.contentSize;
CGRect tableViewRealFrame = self.tableView.frame;
//Size tableView to show the whole content
self.tableView.frame = CGRectMake(0, 0, contentSize.width, contentSize.height);
//Generate PDF (one page)
UIGraphicsBeginPDFContextToData(pdfData,self.tableView.frame, nil);
UIGraphicsBeginPDFPage();
[self.tableView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIGraphicsEndPDFContext();
//Resize frame
self.tableView.frame = tableViewRealFrame;
return pdfData;}
Size the frame to fit the entire content of the scrollView, capture it in graphicsContext, size the frame back.
The upper code generates one page.
For more pages I use basically this:
//MultiPage
CGRect mediaBox = self.tableView.frame;
CGSize pageSize = CGSizeMake(self.view.frame.size.width, 800);
UIGraphicsBeginPDFContextToData(pdfData, CGRectZero, nil);
CGContextRef pdfContext = UIGraphicsGetCurrentContext();
NSInteger currentPage = 0;
BOOL done = NO;
do {
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0.0, pageSize.width, pageSize.height), nil);
CGContextTranslateCTM(pdfContext, 0, -(pageSize.height*currentPage));
[self.view.layer renderInContext:pdfContext];
if ((pageSize.height*(currentPage+1)) > mediaBox.size.height) done = YES;
else currentPage++;
} while (!done);
UIGraphicsEndPDFContext();
回答3:
is it possible to see your sample code please, I am trying to do the same exactly thing.
you could send the source code here, thanks for that you would be very generous dott.marco@mac.com
anyway for your problem maybe this can help:
You are capturing the visible content only because your scroll view is sized match the visible content only, which it should be. You need to resize your scrollview to match the content you need to capture before you start the drawing code using something like this:
Code: self.scrollView.frame = CGRectMake(0, 0, "your content width here", "your content height here"); After you are done drawing make sure to resize your scroll view to back, in this case to the container view:
Code: self.scrollView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
来源:https://stackoverflow.com/questions/5268943/pdf-generation-from-uiscrollview-iphone