2012-07-07 4 views
6

인쇄를 위해 PDF를 작성하는 데 사용되는 코코아 응용 프로그램에서 화면 NSViews의 시퀀스가 ​​있습니다. 뷰는 NSWindow에 없거나 어떤 방식 으로든 볼 수 있습니다.오프 스크린 NSView에서 크기 조정 된 이미지 생성

PDF보기와 똑같은 축소판 이미지를 생성 할 수 있지만 특정 픽셀 크기 (너비 또는 높이 제한)에 맞춰 축소 할 수 있기를 바랍니다. 가능한 한 빨리 처리해야하므로 PDF로 렌더링하지 말고 래스터로 변환 한 다음 스케일을 조정하십시오. 래스터로 직접 가고 싶습니다. 내가 뭘 순간

:이 방법은 잘 작동하지만, 나는 bitmapImageRep을 렌더링하기 전에 NSView의에 스케일링을 적용하는 방법을 작동하지 않을 수

NSBitmapImageRep *bitmapImageRep = [pageView bitmapImageRepForCachingDisplayInRect:pageView.bounds]; 
[pageView cacheDisplayInRect:pageView.bounds toBitmapImageRep:bitmapImageRep]; 
NSImage *image = [[NSImage alloc] initWithSize:bitmapImageRep.size]; 
[image addRepresentation:bitmapImageRep]; 

. scaleUnitSquareToSize을 사용하는 것을 피하고 싶습니다. NSView의 프레임이 아니라 경계 만 변경하기 때문에 이해합니다.

가장 좋은 방법은 무엇입니까?

답변

6

이것이 내가 끝내 었으며 완벽하게 작동합니다. NSBitmapImageRep으로 직접 그려야하지만 미리 CGContextScaleCTM을 사용하여 컨텍스트를 명시 적으로 조정하십시오. graphicsContext.graphicsPortNSGraphicsContext에 대한 CGContextRef 핸들을 제공합니다.

NSView *pageView = [self viewForPageIndex:pageIndex]; 

float scale = width/pageView.bounds.size.width; 
float height = scale * pageView.bounds.size.height; 

NSRect targetRect = NSMakeRect(0.0, 0.0, width, height); 
NSBitmapImageRep *bitmapRep; 

bitmapRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil 
                pixelsWide:targetRect.size.width 
                pixelsHigh:targetRect.size.height 
               bitsPerSample:8 
               samplesPerPixel:4 
                 hasAlpha:YES 
                 isPlanar:NO 
               colorSpaceName:NSCalibratedRGBColorSpace 
                bitmapFormat:0 
                bytesPerRow:(4 * targetRect.size.width) 
                bitsPerPixel:32]; 

[NSGraphicsContext saveGraphicsState]; 

NSGraphicsContext *graphicsContext = [NSGraphicsContext graphicsContextWithBitmapImageRep:bitmapRep]; 
[NSGraphicsContext setCurrentContext:graphicsContext]; 
CGContextScaleCTM(graphicsContext.graphicsPort, scale, scale); 

[pageView displayRectIgnoringOpacity:pageView.bounds inContext:graphicsContext]; 

[NSGraphicsContext restoreGraphicsState]; 

NSImage *image = [[NSImage alloc] initWithSize:bitmapRep.size]; 
[image addRepresentation:bitmapRep]; 

return image; 
+0

시작시 노트북 응용 프로그램의 축소판을 동적으로 생성하기 위해'bitmapImageRepForCacheDisplayInRect :'및'cacheDisplayInRect : toBitmapImageRep :'를 사용하고있었습니다. 시각적 컨텐츠가 많은> 40 페이지 (레이어 호스팅 NSViews)에서 축소판 생성은 90 초 가까이 걸렸습니다. 이전 버전의 macOS에서는 그렇지 않았습니다. 나는이 방법을 위의 @tumtaylor의 접근법으로 바꿨다. 1.0의 눈금을 사용했기 때문에 (엄지 손가락을 풀 사이즈로 늘리려면 엄지 손가락이 필요했기 때문에) 썸네일 세대는 20 초 (배경)로 내려 갔다. – Dalmazio

0

scaleUnitSquareToSize:을 사용하고 bitmapImageRepForCachingDisplayInRect:cacheDisplayInRect:toBitmapImageRep:에 작은 rect를 입력하는 방법은 어떻습니까?

따라서 2의 배율로 축소하면 테두리와 높이가 절반 인 rect를 전달합니다.

+0

저는 NSTextContainer와 함께 Cocoa Text Layout System을 사용하고 있습니다. 내가 알기에 NSView 레벨에서만 가능합니다. – tomtaylor

+0

아, 미안, 내가 오해했다. 나는 당신이 PDF를 보여주고 있다고 생각했지만, 당신은 기존의 뷰로부터 PDF를 생성하고있다. –

+0

새로운 제안을했습니다. 네 계획이 의미가 있다고 생각해. 또한 레이어 기반보기를 사용하고 해당 레이어의 변형을 사용할 수도 있습니다. (저는 iOS에 더 익숙합니다. 자연스러운 일이 될 것입니다.) –