NSImageRep 混乱

发布于 2024-08-02 16:39:30 字数 321 浏览 12 评论 0 原文

我有一个来自 PDF 的 NSImage,因此它有一种 NSPDFImageRep 类型的表示形式。我做了一个图像 setDataRetained:YES;以确保它仍然是 NSPDFImageRep。后来,我想更改页面,所以我得到了代表,并设置了当前页面。这很好。

问题是当我绘制图像时,只显示第一页。

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

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

我缺少什么?

I have an NSImage that came from a PDF, so it has one representation, of type NSPDFImageRep. I do an image setDataRetained:YES; to make sure that it remains a NSPDFImageRep. Later, I want to change the page, so I get the rep, and set the current page. This is fine.

The problem is that when I draw the image, only the 1st page comes out.

My impression is that when I draw an NSImage, it picks a representation, and draws that representation. Now, the image only has one rep, so that's the one that is being drawn, and that's the PDFrep. So, why when I draw the image, is it not drawing the correct page?

HOWEVER, when I draw the representation itself, I get the correct page.

What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

几度春秋 2024-08-09 16:39:31

NSImage 在第一次显示时会对 NSImageRep 进行缓存。对于 NSPDFImageRep,“setCacheMode:”消息无效。因此,将显示的页面将始终是第一页。请参阅 本指南了解更多信息。

那么您有两种解决方案:

  1. 直接绘制表示。
  2. 在 NSImage 上调用“recache”消息来强制所选页面的光栅化。

NSImage does a caching of the NSImageRep, when first displayed. In the case of NSPDFImageRep, the "setCacheMode:" message has no effect. Thus, the page that will be displayed will always be the first page. See this guide for more information.

You have then two solutions:

  1. Drawing the representation directly.
  2. Call the "recache" message on the NSImage to force the rasterization of the selected page.
下雨或天晴 2024-08-09 16:39:31

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

您可能必须应用转换以确保文档最终的大小符合您的要求。使用 CGAffineTransformCGContextConcatCTM 来执行此操作。

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

// 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);

An alternative mechanism to draw a PDF is to use the CGPDF* functions. To do this, use CGPDFDocumentCreateWithURL to create a CGPDFDocumentRef object. Then, use CGPDFDocumentGetPage to get a CGPDFPageRef object. You can then use CGContextDrawPDFPage to draw the page into your graphics context.

You may have to apply a transform to ensure that the document ends up sized like you want. Use a CGAffineTransform and CGContextConcatCTM to do this.

Here is some sample code pulled out of one of my projects:

// 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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文