向 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 - 创建用户而不向他们发送验证电子邮件

将 PHP 错误日志文件存储在脚本目录中,而不向现有脚本添加 PHP 代码

我们可以使用Admob奖励广告而不向用户提供任何奖励吗?

怎么给PDF文件添加数字签名

在不向撤消堆栈添加撤消命令的情况下更改 QTextEdit

将 S3 事件订阅到 SQS 队列而不向世界公开 SQS?