使用或不使用NSAffineTransform旋转NSImage

时间:2009-08-18 14:12:09

标签: objective-c cocoa nsimage image-rotation nsaffinetransform

我在NSView的子类上绘制了一个NSImage。在之前的一个问题中,我帮助将它竖立在左上角。现在,我希望能够旋转图像。我有一个按钮,增加旋转变​​量%4,然后我乘以-90来找到旋转角度。然后我使用NSAffineTransform旋转图像,并将其转换回屏幕。但是,它似乎没有像我期望的那样工作。我有两个问题。

1)当我旋转时,图像中不在前一帧中的区域的部分被正确绘制。然而,之前存在的药水仍然是原始图像。这意味着在几次旋转后,原始直立图像的正方形,然后是旋转图像下方或左侧的矩形。

2)当我重新调整窗口大小时,图像会以原始竖直方向重绘(应该如此)(因为它不应该)。

基本上,我得出的结论是NSAffineTransform不像我认为的那样工作。有没有其他方法来旋转(和翻译)图像?感谢

大代码块:(“WORKS”和“end works”之间的代码是工作代码,只是绘制图像。它来自我之前的问题)。

[OLD CODE DELETED,用新代码替换下来]

感谢

编辑:更多的研究发现,我可以旋转视图,而不是做NSAffineTtransform。这似乎更好。但是,我无法让翻译工作得很好。下面的新代码(删除原始代码以节省空间)

- (void)drawRect:(NSRect)rect
{

//WORKS
    NSRect frame;
    frame.origin = NSZeroPoint;
    frame.size = [image size];
// end works

    float deltaX, deltaY, height, width;

// if the rotate button was just clicked, we need to rotate by 90 deg, otherwise not
    double rotateDeg = justRot ? -90.0 : 0;

    justRot = NO;

// rotate

    deltaX = 0;
    deltaY = 0;

// translate to account for rotation

    height = [image size].height;
    width = [image size].width;

    switch (rotation)
    {
        case 0:
            NSLog(@"No rotation ");
            break;
        case 1: 
            deltaX += width;
            break;
        case 2:
            deltaX += width;
            deltaY +=  height;  
            break;
        case 3:
            deltaY += height;
            break;
    }


    NSPoint orig;
    if (rotation != 0)
    {
        orig.x = -100;
        orig.y = -100;
    }
    [self rotateByAngle: rotateDeg];
    NSLog(@"orig %f %f", orig.x, orig.y);
//  WORKS
    [self setFrame: frame];
    [image drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1];
// end works
    [self translateOriginToPoint: orig];    
}

3 个答案:

答案 0 :(得分:2)

好的,对于历史记录,以防其他人有这个问题,这就是我提出的答案:

框架旋转停留在drawRect中,其他所有内容都移动到rotate方法:

-(void)rotate
{
    float deltaX, deltaY, height, width;

    rotation = (rotation +1) % 4 ;

    deltaX = 0;
    deltaY = 0;

// translate to account for rotation

    height = [image size].height;
    width = [image size].width;

    switch (rotation)
    {
        case 0:
            NSLog(@"No rotation ");
            deltaY -= width;
        break;
        case 1: 
            deltaY -= height;
            break;
        case 2:
            deltaX += height-width;
            deltaY -= height ;  
            break;
        case 3:
            deltaX += height-width;
            deltaY -= width;
            break;
    }

    NSPoint orig;
    orig.x = deltaX;
    orig.y = deltaY;

    [self rotateByAngle: 90.0];
    [self translateOriginToPoint: orig];

    [self setNeedsDisplay:YES];
}

答案 1 :(得分:1)

我猜你想要将图像旋转到它的中心。如果需要,您需要将仿射变换的原点转换为图像的中心,然后旋转,然后转换回来。现在,如果您有剩下的previos位置的工件,可能是因为您没有使用正确的矩形调用 - [NSView setNeedsDisplayInRect:]。请记住,您需要使图像先前和新位置无效。

更新:我刚刚注意到你正在从drawRect:中更改视图的框架。改变框架为时已晚。而是在不改变视图框架的情况下在正确的位置绘制图像。

答案 2 :(得分:1)