Pergunta

Eu tenho um programa simples Obj C que, no momento, permite carregar uma imagem, desenha-lo, e, teoricamente, deveria permitir o zoom e rotação. Estou usando NSAffineTranslations.

Eu quero que a imagem a ser bloqueado para o canto superior esquerdo (Ao contrário do padrão PS / PDF de inferior esquerdo), então estou usando isFlipped, e chamando [Aftrans scaleXBy: 1,0 Yby: -1.0];

O problema é que, por algum motivo, após a primeira vez que meu drawRect é chamado, a transformação não acontece.

Quando eu carregar uma imagem, ele vem para cima, e parece correto. Se eu alterar o tamanho da janela (que chama drawRect), a imagem chama, mas está de cabeça para baixo e invertida. Isto significa que a transformação não tenha efeito. Não vejo qualquer diferença em qualquer um dos dados do 2º tempo passar.

aqui é uma versão simplificada do código:

- (void)drawRect:(NSRect)rect 
{
    // Drawing code here.

//    NSLog(@"window type: %d", [[self window] backingType]);
   NSAffineTransform *afTrans = [[NSAffineTransform alloc] init];
   NSGraphicsContext *context = [NSGraphicsContext currentContext];
   NSSize sz;
   NSRect windowFrame = [[self window] frame];
   NSRect cv =[[[self window] contentView] frame];
   float deltaX, deltaY;
   NSSize superSize = [[self superview] frame].size;
   float height, width, sHeight, sWidth;

   NSRect imageRect;

   sz = [ image size];
   imageRect.size = sz;
   imageRect.origin = NSZeroPoint;

   height = sz.height  ;
   width = sz.width  ;

//    sHeight and sWidth are the hieght and with of the super-view. ie,
//    the size of the whole window view including the space for the
//    scroll bars, etc, but not including the panel or the borders,
   sHeight = superSize.height;
   sWidth = superSize.width;

   [context saveGraphicsState];

   deltaX = 0;
   deltaY = 0;

   deltaY += height; // account for flipping

   [afTrans translateXBy:deltaX yBy:deltaY];

   [afTrans scaleXBy:1.0 yBy:-1.0];

   [afTrans concat];

   NSRect drawingRect = imageRect;
   NSRect frame = imageRect;
   [self setFrame:frame];

   [image drawInRect:drawingRect
         fromRect:imageRect
         operation:NSCompositeSourceOver
         fraction:1];

   [afTrans release];
   [context restoreGraphicsState];
}

ETA:. Aqui está mais um código que pode ser relevante

-(void )setImage:( NSImage * )newImage
{
    [newImage retain];
    [image release];

    rotation = 0;

    zoom = 1.0;

    image = newImage;
    NSSize imageSize = [newImage size];
    NSRect tFrame = [self frame];
    tFrame = [[self window] frame];

    tFrame.size.width = MAX(tFrame.size.width, imageSize.width);
    tFrame.size.height = MAX(tFrame.size.height, imageSize.height);
    [self setFrame:tFrame];

    [self setNeedsDisplay:YES];
}
Foi útil?

Solução

I'm not sure exactly what you're trying to achieve, but if you want to just draw an image in a NSView and keep it in the upper left, you can do something a bit simpler, in your NSView subclass:

- (BOOL)isFlipped
{
    return YES;
}

- (void)setImage:(NSImage *)newImage
{
    [newImage retain];
    [image release];
    image = newImage;

    [image setFlipped:YES];
    [self setNeedsDisplay:YES];
}

- (void)drawRect:(NSRect)rect
{
    [image drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1];

    // Or stretch image to fill view
    //[image drawInRect:[self bounds] fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1];
}

I was also able to get similar results with your code by getting rid of the [self setFrame:...]; calls in drawRect and setImage methods.

Outras dicas

Assuming you're not stripping out code that changes stuff, watch out if you're drawing the image elsewhere. Toolbar items, tables and so on may well change the -flipped property of the image, causing it to draw incorrectly.

Try this around your image drawing line:

BOOL wasFlipped = [image isFlipped];
[image setFlipped:[self isFlipped]];
[image drawInRect:drawingRect
             fromRect:imageRect
            operation:NSCompositeSourceOver
             fraction:1];
[image setFlipped:wasFlipped];

See if that helps. If it does, look elsewhere in your code for something changing the image's flipped property and not putting it back.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top