2009-08-10 179 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