2010-04-06 52 views
2

我正在嘗試將圖像放入圖像對象並渲染成Core Graphics PDF上下文 - 恰好在iPhone上,但這個問題肯定同樣適用於桌面Quartz。這個UIImage是一個簡單的600x800分辨率的白色圖像。如果我(比如說)把它變成一個PNG文件,那個文件看起來和預期完全一樣 - 所以數據是確定的。將UIImage/CGImage呈現到CGPDFContext中會導致...空白!

下面是我在做什麼,以生成PDF:

NSMutableData * outputData = [[NSMutableData alloc] init]; 
CGDataConsumerRef dataConsumer = CGDataConsumerCreateWithCFData((CFMutableDataRef)outputData); 

CFMutableDictionaryRef attrDictionary = NULL;  
attrDictionary = CFDictionaryCreateMutable(NULL, 0, 
             &kCFTypeDictionaryKeyCallBacks, 
             &kCFTypeDictionaryValueCallBacks); 
CFDictionarySetValue(attrDictionary, kCGPDFContextTitle, @"My Awesome Document"); 
CGContextRef pdfContext = CGPDFContextCreate(dataConsumer, NULL, attrDictionary); 
CFRelease(dataConsumer); 
CFRelease(attrDictionary); 
CGImageRef pageImage = [myUIImage CGImage]; 
CGPDFContextBeginPage(pdfContext, NULL); 
CGContextDrawImage(pdfContext, CGRectMake(0, 0, [myUIImage size].width, [myUIImage size].height), pageImage); 
CGPDFContextEndPage(pdfContext); 
CGPDFContextClose(pdfContext); 
CGContextRelease(pdfContext); 

所生成的PDF,這在outputData結束了,似乎是一個有效的PDF文件(正常打開,文檔標題出現在元數據)但它只包含一個空白頁面。

我在做什麼錯?

謝謝。

更新:哈!這是我的錯。我用於生成PNG文件的測試代碼通過不同的路徑獲取數據。 PDF路徑確實收到一個空的圖像。

+0

你動態地創建myUIImage或者是一個加載圖像資源? 如果您用代碼繪製圖像,您能提供源代碼嗎? – 2010-04-10 13:57:13

回答

4

我測試你的代碼它似乎工作。
你確定你的UIImage是有效的,而不是零繪製到上下文時?
我的測試方法加載從主束.png文件和應用程序文件夾中寫入最終的PDF文件:

- (IBAction)outputPDF:(id)sender 
{ 
    NSMutableData* outputData = [[NSMutableData alloc] init]; 
    CGDataConsumerRef dataConsumer = CGDataConsumerCreateWithCFData((CFMutableDataRef)outputData); 
    CFMutableDictionaryRef attrDictionary = NULL;  
    attrDictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 
    CFDictionarySetValue(attrDictionary, kCGPDFContextTitle, @"My Awesome Document"); 
    CGContextRef pdfContext = CGPDFContextCreate(dataConsumer, NULL, attrDictionary); 
    CFRelease(dataConsumer); 
    CFRelease(attrDictionary); 
    UIImage* myUIImage = [UIImage imageNamed:@"tmp.png"]; 
    CGImageRef pageImage = [myUIImage CGImage]; 
    CGPDFContextBeginPage(pdfContext, NULL); 
    CGContextDrawImage(pdfContext, CGRectMake(0, 0, [myUIImage size].width, [myUIImage size].height), pageImage); 
    CGPDFContextEndPage(pdfContext); 
    CGPDFContextClose(pdfContext); 
    CGContextRelease(pdfContext); 
    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString* documentsDirectory = [paths objectAtIndex:0]; 
    NSString* appFile = [documentsDirectory stringByAppendingPathComponent:@"tmp.pdf"]; 
    [outputData writeToFile:appFile atomically:YES]; 
} 
+0

查看原始問題的更新。無論如何,我並不需要這個代理:) - 爲了實際嘗試我的代碼,以及稍後檢查備份,對您的賞金。謝謝。 – 2010-04-11 02:55:00

+0

非常感謝! – 2010-04-11 06:37:37

0

這個問題似乎在iPhone開發SDK論壇已得到解決: PDF creation tutorial

一切歸功於danielb21:這裏是他們的CreatePDFFile方法的翻版:

// Our method to create a PDF file natively on the iPhone 
// This method takes two parameters, a CGRect for size and 
// a const char, which will be the name of our pdf file 
void CreatePDFFile (CGRect pageRect, const char *filename) { 

    // This code block sets up our PDF Context so that we can draw to it 
    CGContextRef pdfContext; 
    CFStringRef path; 
    CFURLRef url; 
    CFMutableDictionaryRef myDictionary = NULL; 
    // Create a CFString from the filename we provide to this method when we call it 
    path = CFStringCreateWithCString (NULL, filename, 
             kCFStringEncodingUTF8); 
    // Create a CFURL using the CFString we just defined 
    url = CFURLCreateWithFileSystemPath (NULL, path, 
             kCFURLPOSIXPathStyle, 0); 
    CFRelease (path); 
    // This dictionary contains extra options mostly for 'signing' the PDF 
    myDictionary = CFDictionaryCreateMutable(NULL, 0, 
              &kCFTypeDictionaryKeyCallBacks, 
              &kCFTypeDictionaryValueCallBacks); 
    CFDictionarySetValue(myDictionary, kCGPDFContextTitle, CFSTR("My PDF File")); 
    CFDictionarySetValue(myDictionary, kCGPDFContextCreator, CFSTR("My Name")); 
    // Create our PDF Context with the CFURL, the CGRect we provide, and the above defined dictionary 
    pdfContext = CGPDFContextCreateWithURL (url, &pageRect, myDictionary); 
    // Cleanup our mess 
    CFRelease(myDictionary); 
    CFRelease(url); 
    // Done creating our PDF Context, now it's time to draw to it 

    // Starts our first page 
    CGContextBeginPage (pdfContext, &pageRect); 

    // Draws a black rectangle around the page inset by 50 on all sides 
    CGContextStrokeRect(pdfContext, CGRectMake(50, 50, pageRect.size.width - 100, pageRect.size.height - 100)); 

    // This code block will create an image that we then draw to the page 
    const char *picture = "Picture"; 
    CGImageRef image; 
    CGDataProviderRef provider; 
    CFStringRef picturePath; 
    CFURLRef pictureURL; 

    picturePath = CFStringCreateWithCString (NULL, picture, 
             kCFStringEncodingUTF8); 
    pictureURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), picturePath, CFSTR("png"), NULL); 
    CFRelease(picturePath); 
    provider = CGDataProviderCreateWithURL (pictureURL); 
    CFRelease (pictureURL); 
    image = CGImageCreateWithPNGDataProvider (provider, NULL, true, kCGRenderingIntentDefault); 
    CGDataProviderRelease (provider); 
    CGContextDrawImage (pdfContext, CGRectMake(200, 200, 207, 385),image); 
    CGImageRelease (image); 
    // End image code 

    // Adding some text on top of the image we just added 
    CGContextSelectFont (pdfContext, "Helvetica", 16, kCGEncodingMacRoman); 
    CGContextSetTextDrawingMode (pdfContext, kCGTextFill); 
    CGContextSetRGBFillColor (pdfContext, 0, 0, 0, 1); 
    const char *text = "Hello World!"; 
    CGContextShowTextAtPoint (pdfContext, 260, 390, text, strlen(text)); 
    // End text 

    // We are done drawing to this page, let's end it 
    // We could add as many pages as we wanted using CGContextBeginPage/CGContextEndPage 
    CGContextEndPage (pdfContext); 

    // We are done with our context now, so we release it 
    CGContextRelease (pdfContext); 
}