2014-11-14 3 views
0

Я пытаюсь использовать CGContextClip(), чтобы сделать какой-то рисунок, однако я сталкиваюсь с некоторыми неприятными проблемами сглаживания. Проблема заключается в том, что заполнение смешивается с цветом, который он заменяет, вместо окружающих пикселей. См. Изображения для немного лучшего описания проблемы!Core Graphics: CGContextClip() Edge Unwanted Weird Antialiasing

Пример вопроса:

enter image description here

(Обратите внимание, что синяя кромка быть сглажена правильно)

Weird сглаженного край:

enter image description here (Край должен быть смешанный с белым, а не голубой)

Код:

-(void) drawRect:(CGRect)rect { 

    CGContextRef c = UIGraphicsGetCurrentContext(); 

    CGContextSaveGState(c); 
    { 

     CGContextBeginPath(c); 
     CGContextAddEllipseInRect(c, CGRectMake(25, 25, 200, 200)); 
     CGContextClosePath(c); 
     CGContextClip(c); 

     CGContextSetFillColorWithColor(c, [UIColor blueColor].CGColor); 
     CGContextFillRect(c, rect); 

     CGContextSetFillColorWithColor(c, [UIColor redColor].CGColor); 
     CGContextFillRect(c, CGRectMake(0, 0, 250, 125)); 

    } 
    CGContextRestoreGState(c); 


} 

Любые идеи о том, как предотвратить это странное сглаживание? Я не могу отключить его, так как края круга по-прежнему нуждаются в сглаживании!

Просто, чтобы быть ясным, это просто пример. Я пытаюсь решить эту проблему на гораздо более сложной форме, где решение только заполнить половину отсечения для начала просто невозможно!

+0

Попробуйте заполнить только половину прямоугольника синим. Есть синий под красным, так что CG делает правильно ... – QED

+0

Это, вероятно, решит проблему в этом случае, однако это не решение, которое я могу применить ко всему остальному! С более сложными формами это просто невозможно. Извините, я должен был разъяснить в OP, что я пытаюсь решить эту проблему по более сложной проблеме, я просто демонстрирую ее с помощью этого примера для простоты. Я отредактирую OP. – Hamish

+0

Кроме того, это определенно неправильное поведение! Было бы разумно, если бы красная заливка не полностью покрывала синий фон (т. Е. Если вокруг круга было 1px синий край), но это так. Если я выключу сглаживание, красный цвет займет всю верхнюю половину круга – Hamish

ответ

0

Ну, это не проблема 100%, но это уменьшает странное сглаживание на значительное количество. Я получил идею от this question. Идея состоит в том, что вы очищаете любой предыдущий рендеринг в области, где вы собираетесь рисовать до рисования, путем изменения режима наложения, чтобы очистить, выполнить рисунок, а затем переключить его в нормальное состояние, а затем повторно рисовать. Модифицированный код выглядит следующим образом:

-(void) drawRect:(CGRect)rect { 

    CGContextRef c = UIGraphicsGetCurrentContext(); 

    CGContextSaveGState(c); 
    { 

     CGContextBeginPath(c); 
     CGContextAddEllipseInRect(c, CGRectMake(25, 25, 200, 200)); 
     CGContextClosePath(c); 
     CGContextClip(c); 

     CGContextSetFillColorWithColor(c, [UIColor blueColor].CGColor); 
     CGContextFillRect(c, CGRectMake(25, 25, 200, 200)); 

     CGContextSetFillColorWithColor(c, [UIColor redColor].CGColor); 
     CGRect r = CGRectMake(0, 0, 250, 125); 

     CGContextSetBlendMode(c, kCGBlendModeClear); 
     CGContextFillRect(c, r); 
     CGContextSetBlendMode(c, kCGBlendModeNormal); 
     CGContextFillRect(c, r); 


    } 
    CGContextRestoreGState(c); 

} 

Если кто-то придумывает лучшее решение, что 100% устраняет эту проблему, а затем разместить его в качестве ответа, и я приму его!

+0

Я вижу, что это довольно старый, так что вы, вероятно, долго двигались дальше. Я начинаю дурачиться с этим материалом, но я заметил, что ваш код ничего не делает о цвете штриха или ширине линии. Возможно ли это просто установить эти параметры (либо цвет, соответствующий заполнению, либо ширина до 0,0)? – user1272965