2012-07-07 7 views
6

Mam sekwencję ekranowych widoków NSView w aplikacji Cocoa, które służą do komponowania pliku PDF do drukowania. Widoki nie są w NSWindow, ani widoczne w żaden sposób.Generowanie przeskalowanego obrazu z pozaekranowego NSView

Chciałbym móc generować obrazy miniatur tego widoku, dokładnie tak, jak wyglądałby PDF, ale zmniejszane, aby dopasować się do określonego rozmiaru piksela (ograniczonego do szerokości lub wysokości). To musi być tak szybkie, jak to możliwe, więc chciałbym uniknąć renderowania do formatu PDF, a następnie konwersji do rastra i skalowania - chciałbym przejść bezpośrednio do rastra.

W tej chwili robię:

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

Podejście to działa dobrze, ale nie mogę dowiedzieć się, jak zastosować skalowanie do NSView przed renderowania bitmapImageRep. Chcę uniknąć używania scaleUnitSquareToSize, ponieważ, jak rozumiem, zmienia tylko granice, a nie ramkę NSView.

Wszelkie sugestie dotyczące najlepszego sposobu na zrobienie tego?

Odpowiedz

6

Oto, co zrobiłem, co działa idealnie. Rysujemy bezpośrednio w NSBitmapImageRep, ale skalujemy kontekst jawnie, używając wcześniej: CGContextScaleCTM. graphicsContext.graphicsPort podaje uchwyt CGContextRef dla NSGraphicsContext.

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

Używałem 'bitmapImageRepForCacheDisplayInRect:' i 'cacheDisplayInRect: toBitmapImageRep:' aby dynamicznie generować miniatury dla aplikacji na notebooka przy uruchomieniu. Z> 40 stronami (hostowane przez warstwy NSView) z dużą ilością treści wizualnych generowanie miniatur trwało blisko 90 sekund. Nie było tak w poprzednich wersjach systemu MacOS. Zastąpiłem tę metodę powyższym podejściem @ tomtaylor, używając skali 1.0 (ponieważ potrzebuję miniaturki, aby skalować płynnie w górę do pełnych rozmiarów) i generowanie miniatur spadło do 20 sekund (tło), przy około połowie użycia pamięci wirtualnej! – Dalmazio

0

Co powiesz na użycie numeru scaleUnitSquareToSize:, a następnie przekazanie w mniejszej poprawce do bitmapImageRepForCachingDisplayInRect: i cacheDisplayInRect:toBitmapImageRep:?

Tak więc, jeśli zmniejszysz ją dwukrotnie, przerzucisz prostokąta do połowy z ograniczeniem i wysokością.

+0

Używam systemu układania tekstu kakaowego wraz z NSTextContainer. Jak rozumiem, jest to możliwe tylko na poziomie NSView. – tomtaylor

+0

Ah, przepraszam, źle mnie zrozumiałem. Myślałem, że wyświetlasz plik PDF, ale * tworzysz * plik PDF z istniejących widoków. –

+0

Zrobiłem kilka nowych sugestii; Myślę, że twój plan ma sens. Możesz także spróbować użyć widoku warstwowego i użyć transformacji na tej warstwie. (Jestem bardziej przyzwyczajony do iOS, gdzie byłoby to naturalne.) –