2012-07-07 17 views
6

私は印刷のためにPDFを構成するために使用されるCocoaアプリケーションでスクリーンNSViewのシーケンスを持っています。ビューは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.graphicsPortは、NSGraphicsContextCGContextRefのハンドルを提供します。

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

0

scaleUnitSquareToSize:を使用してから、bitmapImageRepForCachingDisplayInRect:cacheDisplayInRect:toBitmapImageRep:に小さい方の小文字を入力するとどうなりますか?

したがって、係数を2倍に縮小すると、範囲と高さが半分のrectを渡します。

+0

私はNSTextContainerと共にCocoa Text Layout Systemを使用しています。私が理解しているように、それはNSViewレベルでのみ可能です。 – tomtaylor

+0

ああ、申し訳ありませんが、私は誤解しました。私はあなたがPDFを表示していると思っていましたが、既存のビューから* PDFを作成しています。 –

+0

私はいくつかの新しい提案をしました。私はあなたの計画が理にかなっていると思います。また、レイヤーバックビューを使用し、そのレイヤーでトランスフォームを使用することもできます。 –

関連する問題