iOS:使用CoreGraphics进行两步图像处理

8

我正在使用CoreGraphics(在我的drawRect方法中)尝试将混合模式应用于图像(透明png),然后调整结果的alpha值。我认为这需要分两步完成,但我可能错了。目前为止,我的代码如下(可以正常工作):

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之前设置alpha只会改变混合模式应用的数量,而不是整个图像的alpha。

编辑:已发布屏幕截图

enter image description here

提前致谢。


1
如果在绘制图像之前调用CGContextSetAlpha会怎样?在应用混合之前绘制图像后,您可能还想将其重置为1。 - ughoavgfhw
谢谢,但不幸的是这会使图像和混合模式应用的数量都变暗。也就是说,它将是50%透明度和50%向绿色移动。我希望它100%向绿色移动,然后50%透明。 - Chazbot
我仍然不明白结果应该是什么样子的,你能提供一些图片吗? - Nick Weaver
你试过将 alpha 设置回 1 吗?我测试了一下,认为结果是你想要的。我会发布一个包含我的结果的答案。 - ughoavgfhw
1个回答

8
使用透明层,您可以将混合应用于以100%绘制的图像,并将结果显示为50%。结果如下所示:
Image showing output 我使用了纹理背景,这样您就可以清楚地看到下方的图像对所有内容都是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);

编辑:旧内容已删除,因为它占用了大量空间并且没有帮助。如果您想查看,请查看修订历史记录。


非常感谢您抽出时间来完成这个任务。在上面的例子中,您是正确的;底部图像是使用50%的图像和100%的混合绘制的,但它看起来好像只有对于粉色+蓝色圆圈才是50%透明的。换句话说,灰色背景的50%不会显示在您的底部图像中,这正是我所需要的。顶部的圆圈可以做到这一点,但它的颜色变化不是100%。很抱歉我对细节如此挑剔,再次感谢您的帮助。 - Chazbot
好的,现在我明白你想要什么了,并且我已经想出了如何做到。你需要使用透明图层。我会修改我的帖子来展示这个。 - ughoavgfhw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接