Подтвердить что ты не робот

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

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

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

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

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

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

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

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

4b9b3361

Ответ 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()];