Как компенсировать перевернутую систему координат основной графики для удобного рисования? - PullRequest
30 голосов
/ 23 апреля 2010

Это действительно боль, но всегда, когда я рисую UIImage в -drawRect:, это переворачивается.

Когда я переворачиваю координаты, изображение рисуется правильно, но за счет всех других функций компьютерной графики рисует «неправильно» (перевернуто).

Какова ваша стратегия, когда вам нужно рисовать изображения и другие вещи? Есть ли эмпирическое правило, как не зацикливаться на этой проблеме снова и снова?

Кроме того, одна неприятная вещь, когда я переворачиваю ось Y, состоит в том, что мой CGRect из фрейма UIImageView неверен. Вместо того чтобы исходное положение отображалось в 10,10 вверху слева, как и ожидалось, оно появляется внизу.

Но в то же время все эти обычные функции рисования линий CGContext принимают правильные координаты. Рисование линии в -drawRect с началом координат 10,10 в верхнем левом углу, действительно начнется в верхнем левом углу. Но в то же время это странно, потому что ядро ​​графики на самом деле имеет перевернутую систему координат с y 0 внизу.

Так что кажется, что-то там действительно противоречиво. Рисование с использованием функций CGContext принимает координаты как «ожидаемые» (cmon, никто не думает, что координаты, начиная с нижнего левого угла, это глупо), в то время как рисование любого типа изображения все еще работает «неправильным» способом.

Используете ли вы вспомогательные методы для рисования изображений? Или есть что-нибудь полезное, что делает рисование изображения не боль в заднице?

Ответы [ 5 ]

29 голосов
/ 23 апреля 2010

Проблема: источник находится в левом нижнем углу; положительный у идет вверх (отрицательный у идет вниз).
Цель: Происхождение в левом верхнем углу; положительный у идет вниз (отрицательный у идет вверх).

Решение:

  1. Переместить начало координат вверх по высоте.
  2. Отрицать (умножить на -1) ось y.

Способ сделать это в коде - перевести вверх на высоту границ вида и масштабировать на (1, -1), в указанном порядке.

Существует пара частей Quartz 2D Руководство по программированию , которые имеют отношение к этой теме, включая «Рисование в графическом контексте на iPhone OS» и все глава о преобразованиях . Конечно, вы действительно должны прочитать все это.

9 голосов
/ 31 января 2013

Вы можете сделать это, применив affinetransform к точке, которую вы хотите преобразовать в UIKit связанные координаты. Ниже приведен пример.

// Create a affine transform object
CGAffineTransform transform = CGAffineTransformMakeScale(1, -1);
// First translate your image View according to transform
transform = CGAffineTransformTranslate(transform, 0, - imageView.bounds.size.height);
// Then whenever you want any point according to UIKit related coordinates apply this transformation on the point or rect.
// To get tranformed point
CGPoint newPointForUIKit = CGPointApplyAffineTransform(oldPointInCGKit, transform);
// To get transformed rect
CGRect newRectForUIKit = CGRectApplyAffineTransform(oldPointInCGKit, transform);
4 голосов
/ 20 декабря 2012

Лучшим ответом на эту проблему является использование UIImage метода drawInRect: для рисования вашего изображения. Я предполагаю, что вы хотите, чтобы изображение охватило все границы вашего обзора. Это то, что вы вводите в методе drawRect:.

Вместо:

CGContextRef ctx = UIGraphicsGetCurrentContext();  
UIImage *myImage = [UIImage imageNamed:@"theImage.png"];  
CGImageRef img = [myImage CGImage];
CGRect bounds = [self bounds];
CGContextDrawImage(ctx, bounds, img);

Напишите это:

UIImage *myImage = [UIImage imageNamed:@"theImage.png"];
CGRect bounds = [self bounds];
[myImage drawInRect:bounds];
3 голосов
/ 24 апреля 2010

Это действительно боль, но всегда, когда я рисую UIImage в -drawRect:, он переворачивается.

Вы говорите UIImage рисовать или получаете его CGImage ирисовать это?

Как отмечено в «Рисование в графическом контексте на iPhone OS» , UIImages осознает разницу в координатных пространствах и должен рисовать себя правильно, без необходимости переворачиватьВы сами координируете пространство.

0 голосов
/ 03 декабря 2012
CGImageRef flip (CGImageRef im) {
    CGSize sz = CGSizeMake(CGImageGetWidth(im), CGImageGetHeight(im));
    UIGraphicsBeginImageContextWithOptions(sz, NO, 0);
    CGContextDrawImage(UIGraphicsGetCurrentContext(),
                       CGRectMake(0, 0, sz.width, sz.height), im);
    CGImageRef result = [UIGraphicsGetImageFromCurrentImageContext() CGImage];
    UIGraphicsEndImageContext();
    return result;
}

Вызовите вышеуказанный метод, используя код ниже: Этот код имеет дело с получением левой половины изображения из существующего UIImageview и установкой сгенерированного таким образом изображения в новое представление изображения - imgViewleft

CGContextRef con = UIGraphicsGetCurrentContext();
CGContextDrawImage(con,  
                   CGRectMake(0,0,sz.width/2.0,sz.height),
                   flip(leftReference));
imgViewLeft = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...