Как компенсировать перевернутую систему координат основной графики для удобства рисования?
Это действительно боль, но всегда, когда я рисую UIImage в -drawRect:, он перевернут.
Когда я переворачиваю координаты, изображение рисуется правильно, но ценой всех других функций CG рисуется "неправильно" (перевернуто).
Какова ваша стратегия, когда вы должны рисовать изображения и другие вещи? Есть ли какое-либо эмпирическое правило, как не застрять в этой проблеме снова и снова?
Кроме того, одна неприятная вещь, когда я переворачиваю ось y, заключается в том, что мой CGRect из кадра UIImageView ошибочен. Вместо источника, появляющегося на 10,10 верхних левых, как и ожидалось, он появляется внизу.
Но в то же время все эти обычные функции рисования линии CGContext принимают правильные координаты. рисование линии в -drawRect с началом 10,10 в верхнем левом углу, действительно начнется в левом верхнем углу. Но в то же время это странно, потому что основная графика на самом деле имеет перевернутую систему координат с y 0 внизу.
Итак, похоже, что что-то действительно непоследовательно. Рисование с помощью функций CGContext принимает координаты как "ожидаемые" (cmon, никто не думает в координатах, начиная с нижнего левого, это глупо), а рисование любого изображения по-прежнему работает "неправильно".
Используете ли вы вспомогательные методы для рисования изображений? Или есть что-нибудь полезное, что делает рисунок рисунка не болью в прикладе?
Ответы
Ответ 1
Проблема: Происхождение находится в нижнем левом углу; положительный y идет вверх (отрицательный y идет вниз).
Цель: Происхождение в верхнем левом углу; положительный y идет вниз (отрицательный y идет вверх).
Решение:
- Переместить начало вверх по высоте представления.
- Отменить (умножить на -1) ось y.
Способ сделать это в коде - translate вверх по высоте границ представления и scale с помощью (1, -1) в этом порядке.
Есть несколько частей Quartz 2D Programming Guide, которые относятся к этой теме, включая "Рисование в графический контекст на iPhone OS" и целую главу в разделе Transforms. Конечно, вы действительно должны прочитать все это.
Ответ 2
Это можно сделать, применив 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);
Ответ 3
Лучшим ответом на эту проблему является использование метода 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];
Ответ 4
Это действительно боль, но всегда, когда я рисую UIImage в -drawRect:, он перевернут.
Вы говорите, что UIImage рисует или получает CGImage и рисует это?
Как отмечено в "Рисование в графический контекст на iPhone OS" , UIImages знают о различии в координатных пространствах и должны правильно рисуйте, не заставляя себя перевернуть свое пространство координат.
Ответ 5
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()];