Ganesh Amrule Ganesh Amrule - 9 months ago 65
Objective-C Question

Issue while adding image in PDF using PDFKit on mac OS Sierra

I have just updated my OS X to latest verion 10.12 (OS X Siarra) and It has broken previous pdf generation code. Following is my PDF generation code which creates pdf file from given Image. Now this code generate PDF blank file without image.

PDFDocument *pdf = [[PDFDocument alloc] init];
NSImage *image =[NSImage imageNamed:@"sample"];
PDFPage *page = [[PDFPage alloc] initWithImage:image];
[page setBounds:NSMakeRect(0, 0, 500,700) forBox:kPDFDisplayBoxMediaBox];
[pdf insertPage:page atIndex: [pdf pageCount]];
if([pdf writeToFile: fileName]){
[self showAlert:@"Design pdf has been saved."];

Earlier this was working code in previous version. I have tested on older version 10.11 its also works. Any suggestion what is going wrong or any workaround?

Answer Source

There is an issue in Sierra where images are seen blank on adding to pdf document using PDFKit. You need to use low level Quart 2D programming guide apis to get the correct pdf.

Apple Documentation for it is here.

Sample code -

CFStringRef path = CFStringCreateWithCString (NULL, filename,kCFStringEncodingUTF8);
CFURLRef url = CFURLCreateWithFileSystemPath (NULL, path, kCFURLPOSIXPathStyle, 0);
CFRelease (path);

CFMutableDictionaryRef myDictionary = myDictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(myDictionary, kCGPDFContextTitle, CFSTR("Some property string"));
CFDictionarySetValue(myDictionary, kCGPDFContextCreator, CFSTR("Some property string"));

pageDictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDataRef boxData = CFDataCreate(NULL,(const UInt8 *)&pageRect, sizeof (CGRect));
CFDictionarySetValue(pageDictionary, kCGPDFContextMediaBox, boxData);

CGContextRef pdfContext = CGPDFContextCreateWithURL (url, &pageRect, myDictionary);
CGPDFDocumentRef document = CGPDFDocumentCreateWithURL (url);

ViewController* currentView = [story instantiateControllerWithIdentifier:viewName];

NSImage *currentImage = [self imageRepresentation:currentView.view];

CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)[currentImage TIFFRepresentation], NULL);
CGImageRef maskRef =  CGImageSourceCreateImageAtIndex(source, 0, NULL);

CGPDFContextBeginPage (pdfContext, pageDictionary);
CGContextDrawImage(pdfContext, pageRect, maskRef);
CGPDFContextEndPage (pdfContext);

CGContextRelease (pdfContext);
CGPDFDocumentRelease (pdfDocument);