RGBA 的 CGColorSpace 在哪里?

Posted

技术标签:

【中文标题】RGBA 的 CGColorSpace 在哪里?【英文标题】:Where is the CGColorSpace for RGBA? 【发布时间】:2016-10-08 20:38:18 【问题描述】:

我正在尝试绘制一个带有从白色到透明渐变的阴影的圆圈。我正在使用 Core Graphics。

这是我所拥有的,它绘制了从白色到黑色的渐变:

let colorSpace = CGColorSpaceCreateDeviceRGB();
let colors = [UIColor.white.cgColor, UIColor.black.cgColor] as CFArray;
let locations : [CGFloat] = [0.0, 1.0];
let glowGradient : CGGradient = CGGradient.init(colorsSpace: colorSpace, colors: colors, locations: locations)!;
let ctx = UIGraphicsGetCurrentContext()!;
ctx.drawRadialGradient(glowGradient, startCenter: rectCenter, startRadius: 0, endCenter: rectCenter, endRadius: imageWidthPts/2, options: []);

但是,我不想画白到黑;我想画白色到透明。

为此,我首先尝试将结束颜色更改为UIColor.white.cgColor.copy(alpha: 0.0)(即透明白色)。但是,这失败了:

fatal error: unexpectedly found nil while unwrapping an Optional value

我认为这个错误是由于颜色超出了指定的 RGB 颜色空间 (CGColorSpaceCreateDeviceRGB())。

解决方法似乎是将指定的颜色空间更改为具有 alpha 分量的颜色空间,例如 RGBA。然而,这样的色彩空间似乎并不存在!只有CGColorSpaceCreateDeviceRGBCGColorSpaceCreateDeviceCMYKCGColorSpaceCreateDeviceGray

但是没有可用的带有 alpha 分量的颜色空间是没有意义的。该文档明确描述了对渐变中 alpha 的支持。 The documentation for CGGradient.init 说:

例如,如果颜色空间是 RGBA 颜色空间,并且您想在渐变中使用两种颜色(一种用于起始位置,另一种用于结束位置),那么您需要在 components 中提供 8 个值— 第一种颜色的红色、绿色、蓝色和 alpha 值,然后是第二种颜色的红色、绿色、蓝色和 alpha 值。

这种 RGBA 编码非常有意义,但无法告诉 Core Graphics 我正在使用这种 RGBA 编码,因为没有 RGBA 色彩空间!

RGBA 的CGColorSpace 在哪里?

【问题讨论】:

【参考方案1】:

您不需要 RGBA 色彩空间来绘制透明的径向/线性渐变。 RGB 色彩空间就足够了。如果它没有透明地绘制它,则可能是视图的背景颜色或上下文配置错误。

如果您正在创建一个上下文,您希望确保为不透明传递 false:Iphone How to make context background transparent?

如果您在 UIView 上使用 CALayer,则需要确保将 UIView 的背景颜色设置为 UIColor.clear。如果it's set to nil,你最终会得到与黑色混合的渐变。

【讨论】:

【参考方案2】:

一个稍微不满意的答案:你可以使用.colorSpace 获得上下文的色彩空间。就我而言,它似乎给了我一个 RGBA 空间,但我看不到任何保证。

这是使用.colorSpace的渐变:

let ctx = UIGraphicsGetCurrentContext()!;
let colorSpace = ctx.colorSpace!;
let colorComponents : [CGFloat] = [
 // R    G    B    A
    1.0, 1.0, 1.0, 1.0,
    1.0, 1.0, 1.0, 0.0,
    ];
let locations : [CGFloat] = [0.0, 1.0];
let glowGradient : CGGradient = CGGradient.init(
    colorSpace: colorSpace,
    colorComponents: colorComponents,
    locations: locations,
    count: locations.count
    )!;
ctx.drawRadialGradient(glowGradient, startCenter: rectCenter, startRadius: 0, endCenter: rectCenter, endRadius: imageWidthPts/2, options: []);

在我的例子中,特别令人困惑的是,colorSpace.numberOfComponents 的计算结果为 3,即不是 RGBA,但它仍然正确解释了渐变中的 alpha 分量。 ¯\_(ツ)_/¯

【讨论】:

我知道评论有点晚了,但是从文档中,numberOfComponens 返回:“指定颜色空间中颜色分量的数量,不包括 alpha 值。”因此,在您的情况下评估为 3 是正常的。

以上是关于RGBA 的 CGColorSpace 在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

iOS 上的 CGColorSpace API 和颜色管理状态?

画布将图像拆分为 rgba 组件

如何使用rgba(0,0,0,0.5)使背景变暗

如何通过 Javascript 通过 CSS 获取确切的 RGBa 值?

解决警告:*c* argument looks like a single numeric RGB or RGBA sequence, which should be avoi(图文并茂详细版!!!)

如何从字节数组初始化 RGBA cv::Mat?