Вращение NSImage с или без NSAffineTransform
У меня есть NSImage рисуется на подкласс NSView. В предыдущем вопросе мне помогли нарисовать его вертикально в верхнем левом углу. Теперь я хочу иметь возможность вращать изображение. У меня есть кнопка, которая увеличивает переменную вращения%4, а затем умножаю ее на -90, чтобы найти угол поворота. Затем я использую NSAffineTransform, чтобы повернуть изображение и перевести его обратно на экран. Однако, похоже, что это не работает так, как я ожидаю. У меня две проблемы.
1) Когда я поворачиваю, часть изображения, которая находится в области, которой не было в предыдущем кадре, рисуется правильно. Однако зелье, которое было там ранее, остается в качестве исходного изображения. Это означает, что после нескольких поворотов имеется квадрат исходного вертикального изображения, а затем прямоугольник ниже или слева от повернутого изображения.
2) Когда я изменяю размер окна, изображение перерисовывается (как и должно) в исходной вертикальной ориентации (как и не должно).
По сути, я прихожу к выводу, что NSAffineTransform работает не так, как я думаю. Есть ли другой способ повернуть (и перевести) изображение? Спасибо
большой кусок кода: (код между "РАБОТАМИ" и "окончанием работ" - это рабочий код, который просто рисует изображение. Это было из моего предыдущего вопроса).
[СТАРЫЙ КОД УДАЛЕН, заменен нижним новым кодом]
Спасибо
РЕДАКТИРОВАТЬ: немного больше исследований обнаруживает, что вместо выполнения 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 ответа
Хорошо, для истории, в случае, если у кого-то еще есть этот вопрос, вот ответ, который я придумал:
Вращение кадра остается в 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];
}
Я предполагаю, что вы хотите повернуть изображение вокруг его центра. Если это так, вам нужно перевести начало аффинного преобразования в центр изображения, затем повернуть, а затем перевести обратно. Теперь, если у вас остались артефакты предыдущей позиции, это возможно потому, что вы не вызвали -[NSView setNeedsDisplayInRect:] с правильными прямоугольниками. Помните, что вам нужно сделать недействительными как изображения предыдущих, так и новые позиции.
Обновление: я только что заметил, что вы меняете рамку представления из drawRect:. Слишком поздно менять кадр. Вместо этого нарисуйте изображение в правильном месте, не меняя рамку вида.
Взгляните на мой старый пример кода Transformed Image по адресу: http://developer.apple.com/mac/library/samplecode/Transformed_Image/index.html