2009-07-08 5 views
1

NSView의 하위 클래스가 있는데 그 중 NSImage를 그리는 중입니다. NSAffineTransforms에서 이미지를 회전하고 번역하고 크기를 조정하지 않습니다.NSAffineTransforms가 사용되지 않고 있습니까?

대부분 잘 작동합니다. 그러나 때로는 변환이 활성화되지 않는 것처럼 보일 수도 있습니다.

예를 들어, 창 크기를 조정하면 회전 변환이 수행되지 않습니다.

이미지를 확대하면 이미지의 왼쪽 아래가 올바른 위치에 놓이지 만 확대되지는 않지만 이미지의 오른쪽 부분이 확대됩니다 크기가 큰 이미지. 이것을 회전 시키면 올바르게 확대/축소되지만 잘못 변환됩니다. 나는 그래서 초기에 모든 것의 크기를 잡기 위해 필요 (긴 코드 청크 죄송합니다)

- (void)drawRect:(NSRect)rect 
{ 
    // Drawing code here. 
    double rotateDeg = -90* rotation; 
    NSAffineTransform *afTrans = [[NSAffineTransform alloc] init]; 
    NSGraphicsContext *context = [NSGraphicsContext currentContext]; 
    NSSize sz; 
    NSRect windowFrame = [[self window] frame]; 
    float deltaX, deltaY; 
    NSSize superSize = [[self superview] frame].size; 
    float height, width, sHeight, sWidth; 

    NSRect imageRect; 

    if(image) 
    { 
     sz = [ image size]; 
     imageRect.size = sz; 
     imageRect.origin = NSZeroPoint; 
     imageRect.size.width *= zoom; 
     imageRect.size.height *= zoom; 

     height = sz.height * zoom ; 
     width = sz.width *zoom ; 
     sHeight = superSize.height; 
     sWidth = superSize.width; 
    } 

: 여기

내의 drawRect의 코드합니다 (transation 내 부분에 계산 오류가있을 수 있습니다) 나중에 회전 할 때 사용할 수 있습니다. 나는 그 중 하나를 보호 할 필요가 있는지 모르겠지만, 나는 왼쪽 하단 모서리 중심으로 회전하고있어 이후 나는

[context saveGraphicsState]; 

// rotate 
    [afTrans rotateByDegrees:rotateDeg]; 
// translate to account for window size; 
    deltaX = 0; 
    deltaY = 0; 

// translate to account for rotation 

// in 1 and 3, X and Y are reversed because the entire FRAME 
// (inculding axes) is rotated! 
    switch (rotation) 
    { 
     case 0: 
//   NSLog(@"No rotation "); 
      break; 
     case 1: 
      deltaY -= (sHeight - height); 
      deltaX -= sHeight ; 
      break; 
     case 2: 
      deltaX -= width; 
      deltaY -= (2*sHeight - height);  
      // it's rotating around the lower left of the FRAME, so, 
      // we need to move it up two frame hights, and then down 
      // the hieght of the image 
      break; 
     case 3: 
      deltaX += (sHeight - width); 
      deltaY -= sHeight; 
      break; 
    } 

... C의 년에서 편집증 해요, 내가 할 이미지를 원하는 왼쪽 상단 모서리에 잠겨 있으면 이미지를 옮길 필요가 있습니다. 한 번 회전하면 이미지가 + - 사분면에 있으므로 한 뷰 높이까지 이동하고 왼쪽에서 뷰 높이에서 이미지 높이를 뺀 값까지 이동해야합니다.

[afTrans translateXBy:deltaX yBy:deltaY]; 

// for putting image in upper left 

// zoom 
    [afTrans scaleBy: zoom]; 
    printMatrix([afTrans transformStruct]); 
    NSLog(@"zoom %f", zoom); 
    [afTrans concat]; 

    if(image) 
    { 
     NSRect drawingRect = imageRect; 
     NSRect frame = imageRect; 

     frame.size.height = MAX(superSize.height, imageRect.size.height) ; 
     [self setFrame:frame]; 

     deltaY = superSize.height - imageRect.size.height; 
     drawingRect.origin.y += deltaY; 

이렇게하면 이미지가 프레임의 왼쪽 상단에 표시되도록 프레임이 올바른 크기가됩니다. 이미지가 창보다 크면 프레임이 커져서 스크롤 막대가 나타나기를 원합니다. 그렇지 않으면 프레임이 창 위쪽에 도달 할 정도로 커야합니다.

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

     if((rotation %2)) 
     { 
      float tmp; 
      tmp = drawingRect.size.width; 
      drawingRect.size.width = drawingRect.size.height; 
      drawingRect.size.height = tmp; 
     } 

이 코드는 전적으로 역사적인 것일 수 있습니다.이 코드는 90도 또는 270도 회전했을 때 높이와 너비를 바꿀 수있는 아이디어였습니다.

} 
    else 
     NSLog(@"no image"); 

    [afTrans release]; 
    [context restoreGraphicsState]; 

} 
+0

큰 코드 블록을 더 작은 섹션으로 나누고 각 블록에서 수행하려는 작업을 설명하십시오 (특히 회전을위한 switch 문과 if (이미지) 블록 두 개). 나는 당신의 코드를 프로젝트에서 조롱했다. 그러나 나는 당신이하는 일을 따르려고 노력하는 데 어려움을 겪고있다. – Peter

+0

좋아, 문제 없어요! –

답변

0

왜 슈퍼 뷰 크기를 사용합니까? 그것은 거의 걱정할 필요가없는 것입니다. 특정보기에 포함되는 것에 의존하지 않고 뷰를 자체적으로 작동하게해야합니다.

imageRect의 크기를 조정하는 것은 올바른 방법이 아닙니다. 일반적으로 -drawImage를 호출 할 때 원본 rect를 이미지의 경계로 만들고 대상 rect를 확대/축소하여 확대/축소합니다.

변형을 변경 한 후에 전체보기를 다시 그려 내지 않는 것과 같은 소리를보고하는 문제. 당신은 전화를하고 있습니까? -setNeedsDisplay : 예?

이보기는 창에 어떻게 포함되어 있습니까? 그것은 NSScrollView 안에 있습니까? 스크롤보기가 창과 함께 크기가 조정되었는지 확인 했습니까?

+0

superview의 크기가 필요합니다. 그렇지 않으면 왼쪽 위 모서리가 어디 있는지 모르기 때문입니다. 내 이미지를 왼쪽 아래가 아닌 왼쪽 상단에 고정시키고 싶습니다.나는 isFlipped 메소드를 사용하여이 문제로부터 벗어날 수 있지만, 처음 시작할 때이 방법이 더 깔끔하다고 생각했다. ... drawRect를 사용하여 스케일링을 시도해 볼 수는 있지만, 시도해 볼 가치가 있지만 needsDisplay : YES를 사용하고있다. 뷰는 윈도우 크기에 고정 된 스크롤에 있습니다. –

관련 문제