CGContextClip () с использованием перевернутого пути

Я хочу иметь обрезанный рисунок на моем CGContext, но мне это нужно как раз наоборот, т. Е. Я хочу добавить несколько прямоугольников к моему пути обрезки, используя CGContextAddRect(), и обрезание должно выполняться таким образом, чтобы все прямоугольники, которые я добавил к на мой путь обрезки никакие операции рисования не влияют. Обычно все наоборот, то есть функции рисования рисуют прямоугольники, которые были добавлены к траектории отсечения, и оставляют области, которые не были добавлены к траектории отсечения, нетронутыми. Так что я думаю, что мне нужно просто изменить путь отсечения перед вызовом CGContextClip(). Еще во времена QuickDraw это можно было легко сделать, используя регионы и затем вызывая XorRgn() для каждого прямоугольника. Но с Quartz все сложнее. Есть ли у кого-нибудь простое решение для достижения этой цели, или мне нужно сделать все эти вычисления обратного пути самостоятельно?


person Andreas    schedule 17.05.2012    source источник


Ответы (2)


Вы можете добавить свои границы в виде прямоугольника, а затем добавить прямоугольники, которые вы хотите исключить из рисования, и использовать CGContextEOClip.

Пример:

- (void)drawRect:(NSRect)dirtyRect
    CGContextRef ctx = [[NSGraphicsContext currentContext] graphicsPort];
    //Fill the background with gray:
    CGContextSetRGBFillColor(ctx, 0.5, 0.5, 0.5, 1);
    CGContextFillRect(ctx, NSRectToCGRect(self.bounds));
    CGContextAddRect(ctx, NSRectToCGRect(self.bounds));
    //Add some rectangles:
    CGContextAddRect(ctx, CGRectMake(10, 10, 100, 100));
    CGContextAddRect(ctx, CGRectMake(120, 120, 50, 100));
    //Clip:
    CGContextEOClip(ctx);
    //Fill the entire bounds with red:
    CGContextSetRGBFillColor(ctx, 1.0, 0.0, 0.0, 1.0);
    CGContextFillRect(ctx, NSRectToCGRect(self.bounds));
}

Эффект становится более очевидным, если вы нарисуете изображение в конце вместо заполнения красного прямоугольника.

person omz    schedule 17.05.2012
comment
Хорошая идея, но это не работает, когда прямоугольники обрезки перекрываются. - person Andreas; 17.05.2012
comment
Хорошо, я думаю, теперь у меня это есть. Мне нужно вызвать CGContextEOClip () один раз для каждого прямоугольника отсечения, который я добавляю. Тогда это работает даже с перекрывающимися прямоугольниками! Большое спасибо за подсказку! - person Andreas; 17.05.2012
comment
большое спасибо @omz и @Andreas! Я давно искал этот ответ, но так и не понял, как исправить проблему с перекрывающимися прямоугольниками. идеально :) - person adam.wulf; 03.10.2012
comment
Что, если ваш инвертированный путь состоит из нескольких подпути? EOClip создаст, если они будут перекрываться ... - person araid; 20.02.2014

Один из способов - нарисовать контур обрезки в контексте растрового изображения, инвертировать полученное растровое изображение и использовать его в качестве маски на исходном изображении, вызвав _ 1_.

person user1118321    schedule 17.05.2012
comment
Спасибо, это действительно реальный способ. Тем не менее, мне интересно, есть ли возможность без необходимости проходить маршрут растровой маски. - person Andreas; 17.05.2012