向 pdf 添加签名图像而不向 iOS 中的用户显示 pdf 数据
Posted
技术标签:
【中文标题】向 pdf 添加签名图像而不向 iOS 中的用户显示 pdf 数据【英文标题】:Add a signature image to a pdf without showing the pdf data to user in iOS 【发布时间】:2014-06-02 23:48:59 【问题描述】:我想在现有的 pdf 上添加签名。我通过以下方式做到了这一点:
1) 在 UIView 上加载现有的 pdf,比如 mainView。
2) 在 mainView 上添加签名图片。
3) 调用以下函数
-(NSMutableData *)getPDFDatafromUIView
DebugLog(@"");
// 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, mainView.bounds, nil);
UIGraphicsBeginPDFPage();
CGContextRef pdfContext = UIGraphicsGetCurrentContext();
// draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData
mainView.layer renderInContext:pdfContext];
// remove PDF rendering context
UIGraphicsEndPDFContext();
return pdfData;
4) 这个函数会阻塞你的 UI 一段时间,所以在新线程上调用它
[NSThread detachNewThreadSelector:@selector(launchExportViewForExportDrawing) toTarget:self withObject:nil];
使用上述方法,我得到一个带有签名的 pdf 数据,其中也包含旧的 pdf 数据。
但是对于上述方法,我必须在 UIView 中显示 pdf。如果我想在不加载 UIView、不向用户显示 pdf 的情况下执行上述操作,我该怎么做?
我可以通过创建新的 pdf 页面在 pdf 上添加图像。如何在现有 pdf 上添加图像?
【问题讨论】:
我有pdf的NSData和签名的UIImage。从 ray 的教程 raywenderlich.com/6818/… 中,我可以在 PDF 上添加签名图像。但我不想创建新的 pdf。 “我想在现有 PDF 上添加签名”。 【参考方案1】:我已经通过创建新的 PDF 并在其上绘制 pdf 数据和签名来解决。请参考以下代码:
// For adding the Siganture we need to wite the content on new PDF
-(void) addSignature:(UIImage *) imgSignature onPDFData:(NSData *)pdfData
NSMutableData* outputPDFData = [[NSMutableData alloc] init];
CGDataConsumerRef dataConsumer = CGDataConsumerCreateWithCFData((CFMutableDataRef)outputPDFData);
CFMutableDictionaryRef attrDictionary = NULL;
attrDictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(attrDictionary, kCGPDFContextTitle, CFSTR("My Doc"));
CGContextRef pdfContext = CGPDFContextCreate(dataConsumer, NULL, attrDictionary);
CFRelease(dataConsumer);
CFRelease(attrDictionary);
CGRect pageRect;
// Draw the old "pdfData" on pdfContext
CFDataRef myPDFData = (__bridge CFDataRef) pdfData;
CGDataProviderRef provider = CGDataProviderCreateWithCFData(myPDFData);
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(provider);
CGDataProviderRelease(provider);
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1);
pageRect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
CGContextBeginPage(pdfContext, &pageRect);
CGContextDrawPDFPage(pdfContext, page);
// Draw the signature on pdfContext
pageRect = CGRectMake(0, 0,imgSignature.size.width , imgSignature.size.height);
CGImageRef pageImage = [imgSignature CGImage];
CGContextDrawImage(pdfContext, pageRect, pageImage);
// release the allocated memory
CGPDFContextEndPage(pdfContext);
CGPDFContextClose(pdfContext);
CGContextRelease(pdfContext);
// write new PDFData in "outPutPDF.pdf" file in document directory
NSString *docsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *pdfFilePath =[NSString stringWithFormat:@"%@/outPutPDF.pdf",docsDirectory];
[outputPDFData writeToFile:pdfFilePath atomically:YES];
【讨论】:
此解决方案更改 PDF 中的特定页面并为其添加签名。如果 PDF 有多个页面,则其余页面将丢失。您知道一种可以修改特定 pdf 页面而不会丢失其余页面的方法吗? 您需要通过在 CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1); 中指定页码来将签名添加到所需页面之后,您需要根据要求合并 pdf 页面。 已经有一段时间了,但有没有办法使用此代码在任何地方签署 PDF?因为您将签名添加到硬编码位置 这个有快速版本吗??【参考方案2】:Rohit Answer 运行良好,但它只适用于单页,所以我只是为所有显示图像的页面添加了一些代码(单页铰页中显示的图像看起来相同)。谢谢@Rohit
NSString *path = [[NSBundle mainBundle] pathForResource:@"PartB" ofType:@"pdf"];
NSURL *docURL = [NSURL fileURLWithPath:path];
NSString *pdfName = [NSString stringWithFormat:@"%@",docURL];
NSLog(@"pdfName: %@", pdfName);
NSData *pdfData = [NSData dataWithContentsOfFile:path];
NSURL *pdfURL = [[NSBundle mainBundle] URLForResource:@"PartB.pdf" withExtension:nil];
CGPDFDocumentRef pdf1 = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);
long pageCount = CGPDFDocumentGetNumberOfPages(pdf1);
NSLog(@"the page count %ld",pageCount);
NSMutableData* outputPDFData = [[NSMutableData alloc] init];
CGDataConsumerRef dataConsumer = CGDataConsumerCreateWithCFData((CFMutableDataRef)outputPDFData);
CFMutableDictionaryRef attrDictionary = NULL;
attrDictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(attrDictionary, kCGPDFContextTitle, CFSTR("My Doc"));
CGContextRef pdfContext = CGPDFContextCreate(dataConsumer, NULL, attrDictionary);
CFRelease(dataConsumer);
CFRelease(attrDictionary);
CGRect pageRect;
// Draw the old "pdfData" on pdfContext
CFDataRef myPDFData = (__bridge CFDataRef) pdfData;
CGDataProviderRef provider = CGDataProviderCreateWithCFData(myPDFData);
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(provider);
CGDataProviderRelease(provider);
for (int k=1; k<=pageCount; k++)
CGPDFPageRef page3 = CGPDFDocumentGetPage(pdf, k);
pageRect = CGPDFPageGetBoxRect(page3, kCGPDFMediaBox);
CGContextBeginPage(pdfContext, &pageRect);
CGContextDrawPDFPage(pdfContext, page3);
if (k==pageSelect)
pageRect = CGRectMake(0, 0,100 , 100);
CGImageRef pageImage = [mainImage.image CGImage];
CGContextDrawImage(pdfContext, pageRect, pageImage);
CGPDFContextEndPage(pdfContext);
CGPDFContextClose(pdfContext);
CGContextRelease(pdfContext);
// write new PDFData in "outPutPDF.pdf" file in document directory
NSString *docsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *pdfFilePath =[NSString stringWithFormat:@"%@/outPutPDF.pdf",docsDirectory];
[outputPDFData writeToFile:pdfFilePath atomically:YES];
NSLog(@"save the pdf %@",pdfFilePath);
【讨论】:
【参考方案3】:我不确定我是否完全理解您的问题。据我所知,您有一个 UIView 正在渲染到 PDF 文档上,并且您想要添加签名图像而不是向用户显示。
如果您尝试将“签名图像”添加到您的 pdf,您可以将 UIImageView 添加到您正在渲染到 pdf 的 UIView。
如果您不希望用户同时看到 UIView,您可以将其原点更改为超出范围的位置,例如:
CGRect originalFrame = mainView.frame;
CGRect newFrame = mainView.frame;
newFrame.origin.x = -newFrame.size.width;
newFrame.origin.y = -newFrame.size.height;
mainView.frame = newFrame;
//do all your PDF stuff here
mainView.frame = originalFrame;
我希望这会有所帮助。如果不是,请澄清问题:)
【讨论】:
您好,感谢您的回复。我想在PDF上添加签名,即我有pdf的NSData和签名的UIImage。我怎么做?从 ray 的教程 raywenderlich.com/6818/… 中,我可以在 PDF 上添加签名图像。但我不想创建新的 pdf。 “我想在现有 PDF 上添加签名”。 这应该很容易。不要为输出的 pdf 使用新文件名,只需使用旧文件名。这将覆盖原始文件,您将“更新”原始文件。以上是关于向 pdf 添加签名图像而不向 iOS 中的用户显示 pdf 数据的主要内容,如果未能解决你的问题,请参考以下文章
AWS Cognito - 创建用户而不向他们发送验证电子邮件