核心图像过滤器CISourceOverCompositing在Alpha叠加层中未按预期显示 [英] Core Image filter CISourceOverCompositing not appearing as expected with alpha overlay

查看:464
本文介绍了核心图像过滤器CISourceOverCompositing在Alpha叠加层中未按预期显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用CISourceOverCompositing将文字覆盖在图片上方,当文字图片不是完全不透明时,我得到了意外的结果.在输出的图像中,深色不够深,而浅色太浅.

I’m using CISourceOverCompositing to overlay text on top of an image and I’m getting unexpected results when the text image is not fully opaque. Dark colors are not dark enough and light colors are too light in the output image.

我在简单的情况下重新创建了问题Xcode项目.它使用橙色,白色,黑色文本(用0.3 alpha绘制)创建图像,并且看起来正确.我什至将该图像放入Sketch中,并将其放置在背景图像的顶部,看起来很棒.屏幕底部的图像显示了在Sketch中的外观.问题是,使用CISourceOverCompositing将文本覆盖在背景上之后,白色文本太不透明,好像alpha为0.5,而黑色文本几乎不可见,好像alpha为0.1.顶部图像显示了以编程方式创建的图像.您可以拖动滑块来调整Alpha(默认值为0.3),以重新创建结果图像.

I recreated the issue in a simple Xcode project. It creates an image with orange, white, black text drawn with 0.3 alpha, and that looks correct. I even threw that image into Sketch placing it on top of the background image and it looks great. The image at the bottom of the screen shows how that looks in Sketch. The problem is, after overlaying the text on the background using CISourceOverCompositing, the white text is too opaque as if alpha was 0.5 and the black text is barely visible as if alpha was 0.1. The top image shows that programmatically created image. You can drag the slider to adjust the alpha (defaulted at 0.3) which will recreate the result image.

该代码当然包含在项目中,但也包含在此处.这样会创建带有0.3 alpha的文本叠加层,该叠加层将按预期显示.

The code is included in the project of course, but also included here. This creates the text overlay with 0.3 alpha, which appears as expected.

let colorSpace = CGColorSpaceCreateDeviceRGB()
let alphaInfo = CGImageAlphaInfo.premultipliedLast.rawValue

let bitmapContext = CGContext(data: nil, width: Int(imageRect.width), height: Int(imageRect.height), bitsPerComponent: 8, bytesPerRow: 0, space: colorSpace, bitmapInfo: alphaInfo)!
bitmapContext.setAlpha(0.3)
bitmapContext.setTextDrawingMode(CGTextDrawingMode.fill)
bitmapContext.textPosition = CGPoint(x: 20, y: 20)

let displayLineTextWhite = CTLineCreateWithAttributedString(NSAttributedString(string: "hello world", attributes: [.foregroundColor: UIColor.white, .font: UIFont.systemFont(ofSize: 50)]))
CTLineDraw(displayLineTextWhite, bitmapContext)

let textCGImage = bitmapContext.makeImage()!
let textImage = CIImage(cgImage: textCGImage)

接下来,文本图像将覆盖在背景图像的顶部,这与预期的不一样.

Next that text image is overlaid on top of the background image, which does not appear as expected.

let combinedFilter = CIFilter(name: "CISourceOverCompositing")!
combinedFilter.setValue(textImage, forKey: "inputImage")
combinedFilter.setValue(backgroundImage, forKey: "inputBackgroundImage")
let outputImage = combinedFilter.outputImage!

推荐答案

在来回尝试了很多不同的东西之后,(感谢@andy和@Juraj Antas向正确的方向推动了我),我终于有了答案.因此,绘制到Core Graphics上下文中可以得到正确的外观,但是使用该方法绘制图像会更加昂贵.看来问题出在CISourceOverCompositing,但问题实际上出在以下事实:默认情况下,Core Image滤镜在线性空间中工作,而Core Graphics滤镜在感知空间中工作,这解释了不同的结果.但是,您可以使用不执行颜色管理的Core Image上下文从Core Image过滤器创建Core Graphics图像,从而匹配Core Graphics方法的输出.这样原始代码就可以了,只需要输出不同的图像即可.

After a lot of back and forth trying different things, (thanks @andy and @Juraj Antas for pushing me in the right direction) I finally have the answer. So drawing into a Core Graphics context results in the correct appearance, but it is more costly to draw images using that approach. It seemed the problem was with CISourceOverCompositing, but the problem actually lies with the fact that, by default, Core Image filters work in linear space whereas Core Graphics works in perceptual space, which explains the different results. You can however create a Core Graphics image from the Core Image filter using a Core Image context that performs no color management, thus matching the output of the Core Graphics approach. So the original code was just fine, just had to output the image a bit differently.

let ciContext = CIContext(options: [kCIContextWorkingColorSpace: NSNull()])
let outputImage = ciContext.createCGImage(outputCIImage, from: outputCIImage.extent) 
//this image appears as expected

这篇关于核心图像过滤器CISourceOverCompositing在Alpha叠加层中未按预期显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆