将签名图像添加到pdf,而不向iOS中的用户显示pdf数据

时间:2014-04-18 12:54:14

标签: ios objective-c ipad pdf pdf-generation

我想在现有的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上添加图像?

3 个答案:

答案 0 :(得分:11)

我通过创建新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];

}

答案 1 :(得分:1)

Rohit Answers运作良好,但仅适用于单页,因此我只为所有显示图像的页面添加了一些代码(单页扩孔页面中显示的图像看起来相同)。谢谢@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);

答案 2 :(得分:-1)

我不确定我完全理解你的问题。从我可以告诉你有一个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; 

我希望有所帮助。如果没有,请澄清问题:)