In xcode, how would I convert a UIImage into a PDF File? Once I figure this out, I will send it through an email. But everything I've found while researching, it results as a blank file or gives an error saying it's damaged. How should I convert it?
-(void)createPdf:(NSImage*)image
{
PDFDocument *pdf = [[PDFDocument alloc] init];
NSImage *image = [[NSImage alloc] initWithContentsOfFile:fileName];
PDFPage *page = [[PDFPage alloc] initWithImage:image];
[pdf insertPage:page atIndex: [pdf pageCount]];
[pdf writeToFile:path];
}
USE the above method as follow :
NSImage *image = [[NSImage alloc] initWithContentsOfFile:PATH_OF_YOUR_PNG_FILE];
[self createPdf:image];
PDFDocument Class conforms to NSObject. You can use this PDFDocument class in the PDFKit Framework.
1. Download Source File From Step 4
2. Import into your Project
3. Put This code into your action
NSData *pdfData = [[NSData alloc] init];
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
pdfData = [PDFImageConverter convertImageToPDF:chosenImage];
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent: #"Documents/image.pdf"];
[pdfData writeToFile:path atomically:NO];
4. Enjoy PDFImageConverter
First you need to create a PDF graphics context that is GraphicsBegin and GraphicsEndPDFContext. Your image from current view will capture and it will set on your PDF page.
Steps:
First call this method on any of your button tap event:
NSString *fileName = [NSString stringWithFormat:#“pdf file name here”];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pdfFileName = [documentsDirectory stringByAppendingPathComponent:fileName];
// This method will generate pdf file of your image. You can send that pdf file after this method.
[self generatePdfWithFilePath: pdfFileName];
Then set these methods in your view controller:
- (void) generatePdfWithFilePath: (NSString *)thefilePath
{
UIGraphicsBeginPDFContextToFile(thefilePath, CGRectZero, nil);
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 500, 810), nil);
[self drawImage:#“page number of pdf file”];
UIGraphicsEndPDFContext();
}
- (void) drawImage:(NSInteger)pageNumber
{
UIImage * demoImage1;
demoImage1 = [self captureView:#“Your image view”];
[demoImage1 drawInRect:CGRectMake(0, 0, 500, 810)];
}
- (UIImage *)captureView:(UIView *)view {
CGRect screenRect = view.frame;
UIGraphicsBeginImageContext(screenRect.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
[[UIColor blackColor] set];
CGContextFillRect(ctx, screenRect);
[view.layer renderInContext:ctx];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I want to generate a pdf file with text that will change every time based on my server data. I want to create that pdf file using html in iOS. Any suggestions. Please help.
Thanks in advance.
Please check below link :
https://github.com/iclems/iOS-htmltopdf.
Its have methods for doing that with local html file as well as with URL also.
+ (id)createPDFWithHTML:(NSString*)HTML pathForPDF:(NSString*)PDFpath delegate:(id <NDHTMLtoPDFDelegate>)delegate pageSize:(CGSize)pageSize margins:(UIEdgeInsets)pageMargins;
+ (id)createPDFWithHTML:(NSString*)HTML baseURL:(NSURL*)baseURL pathForPDF:(NSString*)PDFpath delegate:(id <NDHTMLtoPDFDelegate>)delegate pageSize:(CGSize)pageSize margins:(UIEdgeInsets)pageMargins;
+ (id)createPDFWithHTML:(NSString*)HTML pathForPDF:(NSString*)PDFpath pageSize:(CGSize)pageSize margins:(UIEdgeInsets)pageMargins successBlock:(NDHTMLtoPDFCompletionBlock)successBlock errorBlock:(NDHTMLtoPDFCompletionBlock)errorBlock;
+ (id)createPDFWithHTML:(NSString*)HTML baseURL:(NSURL*)baseURL pathForPDF:(NSString*)PDFpath pageSize:(CGSize)pageSize margins:(UIEdgeInsets)pageMargins successBlock:(NDHTMLtoPDFCompletionBlock)successBlock errorBlock:(NDHTMLtoPDFCompletionBlock)errorBlock;
You can try this:
You need to show it on webview like this
-(IBAction)convertPDF:(id)sender {
webViewHeight = [[self.myWebView stringByEvaluatingJavaScriptFromString:#"document.body.scrollHeight;"] integerValue];
CGRect screenRect = self.myWebView.frame;
double currentWebViewHeight = webViewHeight;
while (currentWebViewHeight > 0)
{
imageName ++;
UIGraphicsBeginImageContext(screenRect.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
[[UIColor blackColor] set];
CGContextFillRect(ctx, screenRect);
[self.myWebView.layer renderInContext:ctx];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pngPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%d.png",imageName]];
if(currentWebViewHeight < 960)
{
CGRect lastImageRect = CGRectMake(0, 960 - currentWebViewHeight, self.myWebView.frame.size.width, currentWebViewHeight);
CGImageRef lastImageRef = CGImageCreateWithImageInRect([newImage CGImage], lastImageRect);
newImage = [UIImage imageWithCGImage:lastImageRef];
CGImageRelease(lastImageRef);
}
[UIImagePNGRepresentation(newImage) writeToFile:pngPath atomically:YES];
[self.myWebView stringByEvaluatingJavaScriptFromString:#"window.scrollBy(0,960);"];
currentWebViewHeight -= 960;
}
[self drawPdf];
}
then draw PDF from webview
- (void) drawPdf
{ CGSize pageSize = CGSizeMake(612, webViewHeight);
NSString *fileName = #"Demo.pdf";
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pdfFileName = [documentsDirectory stringByAppendingPathComponent:fileName];
UIGraphicsBeginPDFContextToFile(pdfFileName, CGRectZero, nil);
// Mark the beginning of a new page.
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil);
double currentHeight = 0.0;
for (int index = 1; index <= imageName ; index++)
{
NSString *pngPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%d.png", index]];
UIImage *pngImage = [UIImage imageWithContentsOfFile:pngPath];
[pngImage drawInRect:CGRectMake(0, currentHeight, pageSize.width, pngImage.size.height)];
currentHeight += pngImage.size.height;
}
UIGraphicsEndPDFContext(); }
In viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *path;
NSBundle *bundle = [NSBundle mainBundle];
path = [bundle pathForResource:#"Demo" ofType:#"html"];
NSURL *fileUrl = [NSURL URLWithString:#"https://www.google.com/sites/overview.html"];
[self.myWebView loadRequest:[NSURLRequest requestWithURL:fileUrl]];
}
I have a part which is supposed to save an image into my phone's "Documents" folder and then access it. It saves fine, but the load methods don't really work. Here's my .m code:
- (UIImage*)loadImage
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:
#"photo.png" ];
UIImage *image = [UIImage imageWithContentsOfFile:path];
return image;
studentImage = [[UIImageView alloc] initWithImage: image]; //UIImageView property
}
- (UIImage*)loadBarcode
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* path = [documentsDirectory stringByAppendingPathComponent:
#"barcode.png" ];
NSLog(#"%#", path);
UIImage *image = [UIImage imageWithContentsOfFile:path];
return image;
barcode = [[UIImageView alloc] initWithImage: image]; // UIImageView property
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self loadBarcode];
[self loadImage];
}
The files are definitely there to access, the file paths are correct. But the UIImageViews I'm trying to assign them to come up blank. I'm running out of options. Do you guys have any suggestions as to what it might be?
In loadImage method, the problem is here:
return image;
studentImage = [[UIImageView alloc] initWithImage: image];
You first use return statement which transfers the control and never assign it to the UIImageView control.
It should be something like:
studentImage = [[UIImageView alloc] initWithImage: image];
return image;
One more point, if studentImage is connected through IB, DON'T re-allocate it. Instead use:
studentImage.image = image;
Hope it helps!
Problem is fixed now, was an issue with my property names, but thank you for helping me clean up my code!
I have this code which gets the image inside my UIImage (connected with IB called 'c1_1') and should save in my directory folder:
IBOutlet UIImageView *c1_1;
if (c1_1.image != nil)
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* path = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"/ImagensApp/ImagensClientes/%#_%#_Cliente.jpg",list[0],abc]];
NSData* data = UIImageJPEGRepresentation(c1_1.image, 70);
[data writeToFile:path atomically:YES];
}
This code works, but I want to resize the image to scale 200x200, how I can do this before saving?
Scaling an image is just a few lines of code that
creates a memory bitmap
draws the image into that bitmap
and then gets the new image from the bitmap
like this
- (UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)newSize
{
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake( 0, 0, newSize.width, newSize.height )];
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return( result );
}
this is my first attempt at creating a .pdf file in iOS.
I have a tableview that generates all the data I want to be rendered in a .pdf file.
This is my code for capturing the whole table as an image, generating the pdf from the image and emailing it:
- (IBAction)save:(id)sender {
// save all table
CGRect frame = self.tableView.frame;
frame.size.height = self.tableView.contentSize.height;
self.tableView.frame = frame;
UIGraphicsBeginImageContextWithOptions(self.tableView.bounds.size, self.tableView.opaque, 0.0);
[self.tableView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *saveImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
imageData = UIImagePNGRepresentation(saveImage);
UIImage *image = [UIImage imageWithData:imageData];
UIImageView *imageView = [[UIImageView alloc]initWithImage:image];
[self createPDFfromUIView:imageView saveToDocumentsWithFileName:filename];
}
- (NSMutableData*)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);
return pdfData;
}
-(IBAction)back:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
-(IBAction)email:(id)sender{
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
UIImage *image = [UIImage imageWithData:imageData];
UIImageView *imageView = [[UIImageView alloc]initWithImage:image];
NSMutableData *pdfData = [self createPDFfromUIView:imageView saveToDocumentsWithFileName:filename];
// Attach an image to the email
[mc addAttachmentData:pdfData mimeType:#"application/pdf" fileName:filename];
// Present mail view controller on screen
[self presentViewController:mc animated:YES completion:NULL];
}
- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
switch (result)
{
case MFMailComposeResultCancelled:
NSLog(#"Mail cancelled");
break;
case MFMailComposeResultSaved:
NSLog(#"Mail saved");
break;
case MFMailComposeResultSent:
NSLog(#"Mail sent");
break;
case MFMailComposeResultFailed:
NSLog(#"Mail sent failure: %#", [error localizedDescription]);
break;
default:
break;
}
// Close the Mail Interface
[self dismissViewControllerAnimated:YES completion:NULL];
}
I have tested the imageData and the capture is successful. The pdf gets generated but it is a single page.
The desired outcome is that the image captured by imageData is used to create a multipage pdf.
How should I adapt the 'createPDFfromUIView' method to separate the long image file into multiple pages using A4 standard paper.
Any help would be much appreciated
Try this instead of UIGraphicsBeginImageContextWithOptions
CGRect priorBounds = self.tableView.bounds;
CGSize fittedSize = [self.tableView sizeThatFits:CGSizeMake(priorBounds.size.width, self.tableView.contentSize.height)];
self.tableView.bounds = CGRectMake(0, 0, fittedSize.width, fittedSize.height);
CGRect pdfPageBounds = CGRectMake(0, 0, 612, 792); // Change this as your need
NSMutableData *pdfData = [[NSMutableData alloc] init];
UIGraphicsBeginPDFContextToData(pdfData, pdfPageBounds, nil); {
for (CGFloat pageOriginY = 0; pageOriginY < fittedSize.height; pageOriginY += pdfPageBounds.size.height) {
UIGraphicsBeginPDFPageWithInfo(pdfPageBounds, nil);
CGContextSaveGState(UIGraphicsGetCurrentContext()); {
CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, -pageOriginY);
[self.tableView.layer renderInContext:UIGraphicsGetCurrentContext()];
} CGContextRestoreGState(UIGraphicsGetCurrentContext());
}
} UIGraphicsEndPDFContext();
self.tableView.bounds = priorBounds; // Reset the tableView
// Use the pdfData to
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
filePathPDF = [documentsPath stringByAppendingPathComponent:#"image.pdf"]; //Add the file name
BOOL written = [pdfData writeToFile:filePathPDF atomically:YES];
Today i searched a while for a way to programmatically pasting text in a PDF file in an iOS 7 app. Unfortunately there is no easy way to edit a PDF form. You can use a paid library but that was not an option for me. So i did it by pasting text at specified coordinates by using CGPDF.
This is the way i did it:
- (void)editPDF
{
NSString* fileName = #"new.pdf";
NSArray *arrayPaths =
NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory,
NSUserDomainMask,
YES);
NSString *path = [arrayPaths objectAtIndex:0];
NSString* pdfFileName = [path stringByAppendingPathComponent:fileName];
NSString *templatePath = [[NSBundle mainBundle] pathForResource:#"mytemplate" ofType:#"pdf"];
//create empty pdf file;
UIGraphicsBeginPDFContextToFile(pdfFileName, CGRectMake(0, 0, 792, 612), nil);
CFURLRef url = CFURLCreateWithFileSystemPath (NULL, (CFStringRef)templatePath, kCFURLPOSIXPathStyle, 0);
//open template file
CGPDFDocumentRef templateDocument = CGPDFDocumentCreateWithURL(url);
CFRelease(url);
//get amount of pages in template
size_t count = CGPDFDocumentGetNumberOfPages(templateDocument);
//for each page in template
for (size_t pageNumber = 1; pageNumber <= count; pageNumber++) {
//get bounds of template page
CGPDFPageRef templatePage = CGPDFDocumentGetPage(templateDocument, pageNumber);
CGRect templatePageBounds = CGPDFPageGetBoxRect(templatePage, kCGPDFCropBox);
//create empty page with corresponding bounds in new document
UIGraphicsBeginPDFPageWithInfo(templatePageBounds, nil);
CGContextRef context = UIGraphicsGetCurrentContext();
//flip context due to different origins
CGContextTranslateCTM(context, 0.0, templatePageBounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
//copy content of template page on the corresponding page in new file
CGContextDrawPDFPage(context, templatePage);
//flip context back
CGContextTranslateCTM(context, 0.0, templatePageBounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
//create dictionary for font
UIFont *font = [UIFont fontWithName: #"Courier" size:12];
NSDictionary *attribdict = [[NSDictionary alloc] initWithObjectsAndKeys: font, NSFontAttributeName, nil];
/* Here you can do any drawings */
[#"Test" drawAtPoint:CGPointMake(200, 300) withAttributes:attribdict];
}
CGPDFDocumentRelease(templateDocument);
UIGraphicsEndPDFContext();
[self showPDFFile];
}
-(void)showPDFFile
{
NSString* fileName = #"new.pdf";
NSArray *arrayPaths =
NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory,
NSUserDomainMask,
YES);
NSString *path = [arrayPaths objectAtIndex:0];
NSString* pdfFileName = [path stringByAppendingPathComponent:fileName];
UIWebView* webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)];
NSURL *url = [NSURL fileURLWithPath:pdfFileName];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView setScalesPageToFit:YES];
[webView loadRequest:request];
[self.view addSubview:webView];
}
You only have to find out the CGPoint(s) of the point where you want to paste the text and paste a line for each text.
Very helpful was this link: how to edit a PDF in objective-c?
If anybody has a better solution for this i would appreciate if he/she can answer and post it.