Vra

Vir deel van my aansoek Ek het 'n behoefte om 'n beeld van 'n sekere siening te skep en al sy subviews.

Om dit te doen wat ek skep 'n konteks wat 'n bitmap met dieselfde grootte as die oog vou, maar ek is onseker oor hoe om die oog hiërargie trek daarin. Ek kan trek 'n enkele uitsig net die opstel van die konteks en uitdruklik noem drawRect, maar dit beteken nie hanteer al die subviews.

Ek kan niks sien nie in die NSView koppelvlak wat kan help met hierdie so ek vermoed die oplossing kan op 'n hoër vlak lê.

Was dit nuttig?

Oplossing

Ek het gevind dat die skryf van die tekening kode myself was die beste manier om:

  • deal met potensiaal deursigtigheid kwessies (sommige van die ander opsies nie voeg 'n wit agtergrond om die hele beeld)
  • prestasie was baie beter

Die kode hieronder is nie volmaak nie, omdat dit nie hanteer skalering kwessies wanneer gaan uit skrede na rame, maar dit rekening hou met die isFlipped staat, en werk baie goed vir wat ek gebruik dit vir. Let daarop dat dit net trek die subviews (en die subsubviews, ... rekursief), maar om dit self te ook trek is baie maklik, voeg net 'n [self drawRect:[self bounds]] in die implementering van imageWithSubviews.

- (void)drawSubviews
{
    BOOL flipped = [self isFlipped];

    for ( NSView *subview in [self subviews] ) {

        // changes the coordinate system so that the local coordinates of the subview (bounds) become the coordinates of the superview (frame)
        // the transform assumes bounds and frame have the same size, and bounds origin is (0,0)
        // handling of 'isFlipped' also probably unreliable
        NSAffineTransform *transform = [NSAffineTransform transform];
        if ( flipped ) {
            [transform translateXBy:subview.frame.origin.x yBy:NSMaxY(subview.frame)];
            [transform scaleXBy:+1.0 yBy:-1.0];
        } else
            [transform translateXBy:subview.frame.origin.x yBy:subview.frame.origin.y];
        [transform concat];

        // recursively draw the subview and sub-subviews
        [subview drawRect:[subview bounds]];
        [subview drawSubviews];

        // reset the transform to get back a clean graphic contexts for the rest of the drawing
        [transform invert];
        [transform concat];
    }
}

- (NSImage *)imageWithSubviews
{
    NSImage *image = [[[NSImage alloc] initWithSize:[self bounds].size] autorelease];
    [image lockFocus];
    // it seems NSImage cannot use flipped coordinates the way NSView does (the method 'setFlipped:' does not seem to help)
    // Use instead an NSAffineTransform
    if ( [self isFlipped] ) {
        NSAffineTransform *transform = [NSAffineTransform transform];
        [transform translateXBy:0 yBy:NSMaxY(self.bounds)];
        [transform scaleXBy:+1.0 yBy:-1.0];
        [transform concat];
    }
    [self drawSubviews];
    [image unlockFocus];
    return image;
}

Ander wenke

Jy kan gebruik -[NSView dataWithPDFInsideRect:] om die hele hiërargie van die oog jy dit stuur na 'n PDF lewer, teruggekeer as 'n NSData voorwerp. Jy kan dan doen wat jy wil met wat, insluitend lewer dit in 'n bitmap.

Is jy seker jy wil 'n bitmap verteenwoordiging al? Na alles, kan dit PDF wees (ten minste in teorie) resolusie-onafhanklike.

Jy kan gebruik -[NSBitmapImageRep initWithFocusedViewRect:] nadat sluit fokus op die oog op die oog lewer self (en sy subviews) in die gegewe reghoek

Wat jy wil doen, is uitdruklik reeds beskikbaar. Sien die artikel "NSView Drawing Redirection API" in die 10.4 AppKit release.

Maak 'n NSBitmapImageRep vir caching en duidelik dit:

NSGraphicsContext *bitmapGraphicsContext = [NSGraphicsContext graphicsContextWithBitmapImageRep:cacheBitmapImageRep];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:bitmapGraphicsContext];
[[NSColor clearColor] set];
NSRectFill(NSMakeRect(0, 0, [cacheBitmapImageRep size].width, [cacheBitmapImageRep size].height));
[NSGraphicsContext restoreGraphicsState];

Cache om dit:

-[NSView cacheDisplayInRect:toBitmapImageRep:]

As jy meer wil weet oor die algemeen te trek in 'n bepaalde konteks die hantering van die lig rekursie en deursigtigheid korrek,

-[NSView displayRectIgnoringOpacity:inContext:]

Ja, vir hierdie spesifieke gebruik die-un afgeskaal beeld data is presies wat ek nodig het.

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top