NSImageRep путаница

У меня есть NSImage, который пришел из PDF, поэтому он имеет одно представление, типа NSPDFImageRep. Я делаю изображение setDataRetained:YES; чтобы убедиться, что он остается NSPDFImageRep. Позже я хочу изменить страницу, чтобы получить повтор и установить текущую страницу. Это отлично.

Проблема в том, что когда я рисую изображение, выходит только 1-я страница.

У меня сложилось впечатление, что когда я рисую NSImage, он выбирает представление и рисует это представление. Теперь у изображения есть только один представитель, так что это тот, который рисуется, и это PDFrep. Итак, почему, когда я рисую изображение, оно не рисует правильную страницу?

ОДНАКО, когда я рисую само представление, я получаю правильную страницу.

Что мне не хватает?

2 ответа

NSImage выполняет кеширование NSImageRep при первом отображении. В случае NSPDFImageRep сообщение "setCacheMode:" не имеет никакого эффекта. Таким образом, страница, которая будет отображаться, всегда будет первой страницей. Смотрите это руководство для получения дополнительной информации.

У вас есть два решения:

  1. Рисуем представление напрямую.
  2. Вызовите сообщение "recache" в NSImage, чтобы вызвать растеризацию выбранной страницы.

An alternative mechanism to draw a PDF is to use the CGPDF* functions. Для этого используйте CGPDFDocumentCreateWithURL создать CGPDFDocumentRef объект. Затем используйте CGPDFDocumentGetPage чтобы получить CGPDFPageRef объект. Вы можете использовать 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. Использовать CGAffineTransform а также CGContextConcatCTM сделать это.

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);
Другие вопросы по тегам