使用或不使用 NSAffineTransform 旋转 NSImage
我在 NSView 的子类上绘制了一个 NSImage 。在上一个问题中,我被帮助将它画在左上角。现在,我希望能够旋转图像。我有一个按钮可以增加旋转变量 %4,然后将其乘以 -90 来找到旋转角度。然后,我使用 NSAffineTransform 旋转图像,并将其平移回屏幕上。然而,它似乎并没有按照我预期的方式工作。我有两个问题。
1)当我旋转时,图像中不在前一帧的区域中的部分会被正确绘制。然而,之前的药水却依然是原来的图像。这意味着经过几次旋转后,原始直立图像会出现一个正方形,然后旋转图像下方或左侧会出现一个矩形。
2)当我重新调整窗口大小时,图像会以原始直立方向(不应如此)重新绘制(应如此)。
基本上,我得出的结论是 NSAffineTransform 并不像我想象的那样工作。还有其他方法可以旋转(和平移)图像吗?感谢
大代码块:(“WORKS”和“end Works”之间的代码是绘制图像的工作代码。它来自我之前的问题)。
[旧代码已删除,用新代码替换为较低的代码]
感谢
编辑:更多的研究发现,我可以旋转视图,而不是执行 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];
}
I've got an NSImage being drawn on a subclass of NSView. In a previous question, I was helped to draw it upright in the upper left corner. Now, I want to be able to rotate the image. I have a button that increments a rotation variable %4, and then I multiply this by -90 to find the rotation angle. I then use an NSAffineTransform to rotate the image, and translate it back onto the screen. However, it doesn't seem to be working the way I expect it to. I have two problems.
1) When I rotate, the portion of the image that is in an area that wasn't in the previous frame gets drawn correctly. However, the potion that was previously there remains as the original image. This means that after several rotations, there's a square of the original upright image and then a rectangle below or to the left of rotate image.
2) When I re-size the window, the image redraws (as it should) in the original upright orientation (as it should not).
Basically, I'm coming to the conclusion that NSAffineTransform doesn't work the way I think it does. Is there some other way to rotate (and translate) the image? thanks
large code chunk: (code between "WORKS" and "end works" is working code to just draw the image. It came from my previous question).
[OLD CODE DELETED, replaced lower with new code]
thanks
EDIT: A little more research finds that instead of doing an NSAffineTtransform I can rotate the view. This seems to work better. However, I can't get the translation to work quite right. new code below (original code deleted to save space)
- (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];
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好吧,对于历史,如果其他人有这个问题,这是我想出的答案:
框架旋转保留在drawRect中,其他所有内容都移动到旋转方法:
Ok, for history, in case anyone else has this question here's the answer I've come up with:
The frame rotation stays in the drawRect, everything else moves to the rotate method:
我猜您想围绕图像的中心旋转图像。如果是这样,您需要将仿射变换的原点平移到图像的中心,然后旋转,然后平移回来。现在,如果您留下了先前位置的痕迹,可能是因为您没有使用正确的矩形调用 -[NSView setNeedsDisplayInRect:] 。请记住,您需要使之前和新位置的图像都无效。
更新:我刚刚注意到您正在从drawRect: 中更改视图的框架。到时候改变框架就太晚了。相反,在正确的位置绘制图像而不更改视图的框架。
I'm guessing that you'd like to rotate the image about it's center. If so you need to translate the origin of the affine transform to the center of the image, then rotate, then translate back. Now if you have artifacts of the previos position left over, it's probably because you didn't call -[NSView setNeedsDisplayInRect:] with the correct rectangles. Remember that you need to invalidate both the images previous and new positions.
Update: I just noticed that you're changing the view's frame from within drawRect:. That's too late to change the frame. Instead, draw the image in the correct location without changing the view's frame.
看看我旧的转换图像示例代码: http:// developer.apple.com/mac/library/samplecode/Transformed_Image/index.html
Have a look at my old Transformed Image sample code at: http://developer.apple.com/mac/library/samplecode/Transformed_Image/index.html