2

我有一个来自 PDF 的 NSImage,所以它有一个 NSPDFImageRep 类型的表示。我做了一个图像 setDataRetained:YES; 以确保它仍然是 NSPDFImageRep。后来想换个页面,所以得到rep,设置当前页面。这可以。

问题是当我绘制图像时,只有第一页出来。

我的印象是,当我绘制一个 NSImage 时,它​​会选择一个表示,然后绘制该表示。现在,图像只有一个代表,所以这就是正在绘制的那个,那就是 PDFrep。那么,为什么当我绘制图像时,它没有绘制正确的页面?

但是,当我绘制表示本身时,我得到了正确的页面。

我错过了什么?

4

2 回答 2

1

绘制 PDF 的另一种机制是使用 CGPDF* 函数。为此,请使用CGPDFDocumentCreateWithURL来创建一个CGPDFDocumentRef对象。然后,用于CGPDFDocumentGetPage获取CGPDFPageRef对象。然后,您可以使用CGContextDrawPDFPage将页面绘制到您的图形上下文中。

您可能必须应用转换以确保文档最终达到您想要的大小。使用CGAffineTransformandCGContextConcatCTM来执行此操作。

这是从我的一个项目中提取的一些示例代码:

// use your own constants here
NSString *path = @"/path/to/my.pdf";
NSUInteger pageNumber = 14;
CGSize size = [self frame].size;

// if we're drawing into an NSView, then we need to get the current graphics context
CGContextRef context = (CGContextRef)([[NSGraphicsContext currentContext] graphicsPort]);

CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)path, kCFURLPOSIXPathStyle, NO);
CGPDFDocumentRef document = CGPDFDocumentCreateWithURL(url);
CGPDFPageRef page = CGPDFDocumentGetPage(document, pageNumber);

// in my case, I wanted the PDF page to fill in the view
// so we apply a scaling transform to fir the page into the view
double ratio = size.width / CGPDFPageGetBoxRect(page, kCGPDFTrimBox).size.width;
CGAffineTransform transform = CGAffineTransformMakeScale(ratio, ratio);
CGContextConcatCTM(context, transform);

// now we draw the PDF into the context
CGContextDrawPDFPage(context, page);

// don't forget memory management!
CGPDFDocumentRelease(document);
于 2009-12-17T18:36:57.773 回答
1

NSImage 在首次显示时会缓存 NSI​​mageRep。对于 NSPDFImageRep,“setCacheMode:”消息无效。因此,将显示的页面将始终是第一页。有关更多信息,请参阅本指南

你有两个解决方案:

  1. 直接绘制表示。
  2. 调用 NSImage 上的“重新缓存”消息以强制对所选页面进行光栅化。
于 2009-12-16T12:52:07.693 回答