2009-08-10 212 views
4

我有一个简单的Obj C程序,目前它允许您加载图像,绘制图像,理论上可以让您缩放和旋转。我正在使用NSAffineTranslations。我想要图像被锁定在左上角(与左下角的PS/PDF标准相反),所以我使用isFlipped,并调用[afTrans scaleXBy:1.0 yBy:-1.0];在NSView中绘制图像

问题是,由于某种原因,第一次调用drawRect后,转换不会发生。

当我加载图像时,它出现,看起来正确。如果我改变窗口的大小(调用drawRect),图像会画出来,但是会颠倒并颠倒过来。这意味着转换不会生效。我没有看到第二次通过任何数据的任何差异。

这里是代码的精简版:

- (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]; 
} 

埃塔:这里的一些代码,可能是相关的。

-(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]; 
} 
+0

[蟋蟀]我已经有风滚草徽章......如果这是一个晦涩难懂的问题,我觉得自己没有想出来更好 - ) – 2009-08-12 17:32:44

回答

21

我不确定你想要达到什么目的,但是如果你只想在NSView中绘制图像并将其保存在左上角,可以在NSView子类中做一些简单的事情:

- (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]; 
} 

我也能够通过摆脱中的drawRect和setImage方法[self setFrame:...];电话让你的代码相似的结果。

+0

好吧,我需要添加setframes,否则滚动条不正确。但是,这种简化工作!谢谢! – 2009-08-17 14:30:15

+0

平铺图像会如何实现? – uchuugaka 2013-05-23 15:47:35

3

假设您没有剥离改变内容的代码,请留意您是否在其他地方绘制图像。工具栏项目,表格等可能会更改图像的 - flip属性,导致它不正确地绘制。

试试这个图像周围绘制行:

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

看看是否有帮助。如果它确实是,请在您的代码的其他地方查看更改图像翻转属性并不放回原处的内容。

+0

isFlipped方法没有改变,它总是返回YES。 当我添加此代码(它总是将翻转为1,绘制它,并将其设置回0)时,它会启动UPSIDE DOWN,然后在重新绘制时正确翻转。 WTH在这里? – 2009-08-14 18:42:11

+2

必须有其他事情正在进行 - 我将上面的代码粘贴到一个新的NSView类中,并且图像始终正确绘制。你是否在视图的isFlipped中设置了视图本身的isFlipped属性?是这样的,初始平局可能在isFlipped被设定之前发生。 – iKenndac 2009-08-14 18:47:50

+0

不,我硬是在isFlipped ...它似乎总是设置为YES,当我NSLog它... 但另一个问题是,我认为这是affineTransform,因为它似乎仿射当我改变窗口大小时,变换不会发生。至少,它是做同样的事情,因为它我会注释掉仿射变换... – 2009-08-14 19:04:35