2012-07-07 60 views
6

我在Cocoa應用程序中有一系列屏幕外NSView,用於組合PDF打印。視圖不在NSWindow中,或以任何方式顯示。從屏幕外生成縮放圖像NSView

我希望能夠生成該視圖的縮略圖圖像,完全按照PDF查看,但按比例縮小以適合某個像素大小(限制爲寬度或高度)。這需要儘可能快,所以我想避免渲染爲PDF,然後轉換爲光柵和縮放 - 我想直接轉到光柵。

在我做的那一刻:

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

這種方法是行之有效的,但我不能工作,如何渲染bitmapImageRep之前應用的縮放比例調整的NSView。我想避免使用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中並不是這種情況。我用上面的@ tomtaylor的方法替換了這個方法,使用了1.0的縮放比例(因爲我需要縮略圖將流暢地向上縮放到全尺寸),縮略圖生成降到20秒(背景),大約有一半的虛擬內存使用! – Dalmazio 2017-07-09 00:49:18

0

如何使用scaleUnitSquareToSize:然後通過一個較小的矩形bitmapImageRepForCachingDisplayInRect:cacheDisplayInRect:toBitmapImageRep:

所以,如果你將它縮小2倍,你就會將邊界和高度的一半傳遞給矩形。

+0

我正在使用可可文本佈局系統,以及NSTextContainer。據我瞭解,這隻能在NSView級別。 – tomtaylor 2012-07-07 19:14:51

+0

啊,對不起,我誤解了。我以爲你正在顯示一個PDF,但你從現有的視圖創建一個PDF。 – 2012-07-07 20:43:21

+0

我提出了一些新的建議;我認爲你的計劃是有道理的。您也可以嘗試使用圖層背景視圖並在該圖層上使用變換。 (我更習慣於iOS,這是很自然的事情。) – 2012-07-07 20:53:20