我有一个来自PDF的NSImage,因此它有一个NSPDFImageRep类型的表示。我做了一个图像setDataRetained:YES;确保它仍然是NSPDFImageRep。后来,我想更改页面,所以我得到了代表,并设置了当前页面。这很好。
问题在于,当我绘制图像时,只有第一页出现。
我的印象是,当我绘制NSImage时,它会选择一个表示,并绘制该表示。现在,图像只有一个代表,因此就是正在绘制的代表,那就是PDFrep。那么,为什么当我绘制图像时,是不是绘制了正确的页面?
然而,当我绘制表示本身时,我得到了正确的页面。
我错过了什么?
答案 0 :(得分:1)
首次显示时,NSImage会对NSImageRep进行缓存。对于NSPDFImageRep,“setCacheMode:”消息无效。因此,将显示的页面将始终是第一页。有关详细信息,请参阅this guide。
然后你有两个解决方案:
答案 1 :(得分:1)
绘制PDF的另一种机制是使用CGPDF *函数。为此,请使用CGPDFDocumentCreateWithURL
创建CGPDFDocumentRef
对象。然后,使用CGPDFDocumentGetPage
获取CGPDFPageRef
对象。然后,您可以使用CGContextDrawPDFPage
将页面绘制到图形上下文中。
您可能必须应用转换以确保文档的大小最终符合您的要求。使用CGAffineTransform
和CGContextConcatCTM
执行此操作。
以下是我的一个项目中的一些示例代码:
// 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);