1

我有一个 NSView 的子类,其中我正在绘制一个 NSImage。我正在取消使用 NSAffineTransforms 来旋转、平移和缩放图像。

大部分工作正常。但是,有时,转换似乎并没有被激活。

例如,当我调整窗口大小时,不会发生旋转变换。

当我放大图像时,它会将图像的左下角放在正确的位置,但不会放大它,但它会放大原始大小图像右侧的图像部分。如果我旋转它,它会正确缩放,但翻译错误。(交易可能是我的计算错误)

这是我的drawRect的代码:(对不起,长代码块)

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

我需要尽早获取所有内容的大小,以便稍后在旋转时使用它们。我不确定我是否需要保护任何这些,但我对多年的 C 持偏执...

    [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;
    }

由于我在左下角旋转,并且我希望图像被锁定在左上角,所以我需要移动图像。当我旋转一次时,图像在 +- 象限中,所以我需要将它向上移动一个视图高度,向左移动一个视图高度减去图像高度。等等

    [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];

}
4

1 回答 1

0

你为什么使用superview的大小?这是您几乎不需要担心的事情。您应该使视图独立工作,而不依赖于嵌入到任何特定视图中。

缩放 imageRect 的大小可能不是正确的方法。通常在调用 -drawImage 时,您希望源矩形成为图像的边界,并缩放目标矩形以对其进行缩放。

您报告的问题听起来像是您在更改转换后没有重绘整个视图。你在打电话 -setNeedsDisplay: YES 吗?

这个视图是如何嵌入到窗口中的?它在 NSScrollView 内吗?您是否确保滚动视图随窗口一起调整大小?

于 2009-07-19T00:49:54.550 回答