iOS: двухэтапная обработка изображений с помощью CoreGraphics

Используя CoreGraphics (внутри моего метода drawRect), я пытаюсь применить режим наложения к изображению (прозрачный png), а затем настроить альфа-канал результата. Я предполагаю, что это нужно сделать в два этапа, но могу ошибаться. Вот что у меня есть до сих пор (что отлично работает):

CGContextRef context = UIGraphicsGetCurrentContext();

CGContextSaveGState(context);

//SET COLOR - EDIT... added a more practical color example
CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 1);

//flips drawing context (apparently this is necessary)
CGContextTranslateCTM(context, 0.0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);//flip context

//DRAW PIN IMAGE
UIImage *pin = [UIImage imageNamed:@"pin"];
CGRect pinrect = CGRectMake(12, 17, 25, 25);    
CGContextDrawImage(context, pinrect, pin.CGImage);//draws image in context

//Apply blend mode
CGContextSetBlendMode(context, kCGBlendModeColor); 
CGContextClipToMask(context, pinrect, pin.CGImage); // restricts drawing to within alpha channel

//fills context with mask, applying blend mode
CGContextFillRect(context, pinrect); 

CGContextRestoreGState(context);

// -- Do something here to make result 50% transparent ?? --

Я предполагаю, что мне нужно нарисовать все это где-то в каком-то отдельном контексте, вызвать CGContextSetAlpha(...), а затем перерисовать обратно в исходный контекст, но я не уверен, как это сделать. Установка альфы перед моим окончательным CGContextFillRect просто изменит количество примененного режима наложения, а не альфу всего изображения.

РЕДАКТИРОВАТЬ: опубликован скриншот

введите здесь описание изображения

Заранее спасибо.


person Chazbot    schedule 05.05.2011    source источник
comment
Что, если вы вызовете CGContextSetAlpha до того, как отрисуете изображение? Вы также можете сбросить его до 1 после того, как нарисуете изображение, но до того, как примените переход.   -  person ughoavgfhw    schedule 06.05.2011
comment
Спасибо, но, к сожалению, это выцветает как изображение, так и степень применения режима наложения. т.е. Он будет на 50% прозрачным, а на 50% сдвинутым на зеленый. Я хочу, чтобы он на 100% был зеленым, а затем прозрачным на 50%.   -  person Chazbot    schedule 07.05.2011
comment
Я до сих пор не понимаю, как должен выглядеть результат, можете ли вы предоставить несколько фотографий, пожалуйста?   -  person Nick Weaver    schedule 07.05.2011
comment
Вы пытались установить альфу обратно на 1? Я проверил это, и я думаю, что результат - это то, что вы ищете. Я опубликую ответ, включая мой результат.   -  person ughoavgfhw    schedule 07.05.2011


Ответы (1)


Используя слои прозрачности, вы можете применить переход к изображению, нарисованному с масштабом 100%, и отобразить результат с масштабом 50%. Результат выглядит следующим образом:
Изображение, показывающее выводЯ использовал текстурированный фон, чтобы вы могли четко видеть, что нижнее изображение на 50% прозрачно для всего, а не только другое изображение, как в моей предыдущей попытке. Вот код:

CGContextRef context = UIGraphicsGetCurrentContext();

CGContextTranslateCTM(context, 0.0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);//flip context

CGRect fullImageRect = (CGRect){42,57,100,100};
CGRect transparentImageRect = (CGRect){12,17,100,100};
CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 1);

// Draw image at 100%
UIImage *testImage = [UIImage imageNamed:@"TestImage"];
CGContextDrawImage(context,fullImageRect,testImage.CGImage);

// Set 50% transparency and begin a transparency layer. Inside the transparency layer, the alpha is automatically reset to 1.0
CGContextSetAlpha(context,0.5);
CGContextBeginTransparencyLayer(context, NULL);
// Draw the image. It is viewed at 100% within the transparency layer and 50% outside the transparency layer.
CGContextDrawImage(context, transparentImageRect, testImage.CGImage);
// Draw blend on top of image
CGContextClipToMask(context, transparentImageRect, testImage.CGImage);
CGContextSetBlendMode(context, kCGBlendModeColor);
CGContextFillRect(context, transparentImageRect);
// Exit transparency layer, causing the image and blend to be composited at 50%.
CGContextEndTransparencyLayer(context);

Редактировать: Старый контент удален, так как он занимал много места и был бесполезен. Загляните в историю изменений, если хотите.

person ughoavgfhw    schedule 07.05.2011
comment
Большое спасибо за то, что собрали это вместе. В приведенном выше примере вы правы; нижнее изображение нарисовано с изображением в масштабе 50 % и переходом в 100 %, но выглядит так, как будто оно прозрачно только на 50 % для розового+синего круга. Другими словами, 50% серого фона не видно через ваше нижнее изображение, что мне и нужно. Верхний круг делает это, но изменение цвета не на 100%. Извините, что привязываюсь к деталям, и еще раз спасибо за вашу помощь. - person Chazbot; 08.05.2011
comment
Хорошо, теперь я понял, чего ты хочешь, и понял, как это сделать. Вам нужно использовать слои прозрачности. Я изменю свой пост, чтобы показать это. - person ughoavgfhw; 08.05.2011