在NSView中绘制图像

时间:2009-08-10 21:58:10

标签: objective-c image-processing nsview nsaffinetransform

我有一个简单的Obj C程序,目前,它允许你加载图像,绘制它,理论上应该让你缩放和旋转。我正在使用NSAffineTranslations。

我希望图像锁定在左上角(与左下角的PS / PDF标准相对),所以我使用isFlipped,并调用[afTrans scaleXBy:1.0 yBy:-1.0];

问题在于,由于某些原因,在第一次调用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];
}

ETA:这里有一些可能相关的代码。

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

2 个答案:

答案 0 :(得分:22)

我不确定你想要实现什么,但是如果你想在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:...];调用来获得类似的结果。

答案 1 :(得分:3)

假设您没有删除更改内容的代码,请注意您是否将图像绘制到其他位置。工具栏项目,表格等可能会更改图像的-flipped属性,导致其绘制不正确。

在图像绘制线周围尝试:

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

看看是否有帮助。如果它 ,请在代码中的其他位置查找更改图像的翻转属性而不是将其放回的内容。