Mac OS X:如何将多个NSView绘制成一个新的多页PDF?(Mac OS X: How to draw multiple NSViews into a new, multi-page PDF?)

我有一个与图形相关的基于文档的Mac应用程序。 我的应用程序的文档可能有多个“页面”。 每个页面都有一个NSView “canvas”对象。

我的应用程序有几个导出选项,这些选项实现为返回NSData对象(然后写入磁盘)的方法。

我想在一个方法中实现PDF导出选项:

创建内存中的PDF 通过我的文档的画布视图循环并在内存PDF中的新页面中呈现每个视图 返回内存中的多页PDF作为NSData

下面的代码是我目前正在尝试的。

我的文档中的每个页面都是800 x 600像素。

当我将生成的NSData对象写入磁盘时,写入操作成功,但磁盘上的文件以某种方式损坏。 该文件无法在预览或我尝试过的任何其他应用程序中打开。

我究竟做错了什么?

NSMutableData *data = [NSMutableData data]; CGDataConsumerRef consumer = CGDataConsumerCreateWithCFData((CFMutableDataRef)data); CGRect mediaBox = CGRectMake(0.0, 0.0, 800.0, 600.0); CGContextRef ctx = CGPDFContextCreate(consumer, &mediaBox, NULL); CFRelease(consumer); NSGraphicsContext *gc = [NSGraphicsContext graphicsContextWithGraphicsPort:ctx flipped:NO]; for (NSView *canvas in myCanvases) { CGContextBeginPage(ctx, &mediaBox); CGContextSaveGState(ctx); [canvas displayRectIgnoringOpacity:mediaBox inContext:gc]; CGContextRestoreGState(ctx); CGContextEndPage(ctx); } CGPDFContextClose(ctx); // UPDATE: this line was originally missing. see answer below CGContextRelease(ctx); ... NSError *err = nil; if (![data writeToFile:s options:NSDataWritingAtomic error:&err]) { if (err) { NSLog(@"%@", err); } }

I have a graphics-related Document-based Mac App. My app's Documents may have multiple "pages". Each page has an NSView "canvas" object.

My app has several export options which are implemented as methods which return an NSData object (which is then written to disk).

I would like to implement a PDF export option in a method which:

Creates an in-memory PDF loops thru my document's canvas views and renders each in a new page in the in-memory PDF returns the in-memory, multi-page PDF as an NSData

The code below is what I am currently trying.

Each page in my document is 800 x 600 pixels.

When I write the resulting NSData object to disk, the write operation succeeds, but the file on disk is corrupted somehow. The file cannot be opened in Preview or any other app I've tried.

What am I doing wrong?

NSMutableData *data = [NSMutableData data]; CGDataConsumerRef consumer = CGDataConsumerCreateWithCFData((CFMutableDataRef)data); CGRect mediaBox = CGRectMake(0.0, 0.0, 800.0, 600.0); CGContextRef ctx = CGPDFContextCreate(consumer, &mediaBox, NULL); CFRelease(consumer); NSGraphicsContext *gc = [NSGraphicsContext graphicsContextWithGraphicsPort:ctx flipped:NO]; for (NSView *canvas in myCanvases) { CGContextBeginPage(ctx, &mediaBox); CGContextSaveGState(ctx); [canvas displayRectIgnoringOpacity:mediaBox inContext:gc]; CGContextRestoreGState(ctx); CGContextEndPage(ctx); } CGPDFContextClose(ctx); // UPDATE: this line was originally missing. see answer below CGContextRelease(ctx); ... NSError *err = nil; if (![data writeToFile:s options:NSDataWritingAtomic error:&err]) { if (err) { NSLog(@"%@", err); } }

最满意答案

OP在这里。 我已经解决了这个问题。 我错过了对CGPDFContextClose()的最后调用。

所以在发布上下文之前......

CGPDFContextClose(ctx); CGContextRelease(ctx);

OP here. I have solved the problem. I was missing a final call to CGPDFContextClose().

So before releasing the context...

CGPDFContextClose(ctx); CGContextRelease(ctx);

更多推荐