CGBitmapInfo和CGImageAlphaInfo的位运算

12

我在使用Swift时对于CGImageAlphaInfoCGBitmapInfo位操作遇到了麻烦。

具体来说,我不知道如何将这段Objective-C代码转换:

bitmapInfo &= ~kCGBitmapAlphaInfoMask;
bitmapInfo |= kCGImageAlphaNoneSkipFirst;

下面这个简单的 Swift 移植会在最后一行产生有些难以理解的编译器错误 'CGBitmapInfo' is not identical to 'Bool'
bitmapInfo &= ~CGBitmapInfo.AlphaInfoMask
bitmapInfo |= CGImageAlphaInfo.NoneSkipFirst

查看源代码,我注意到CGBitmapInfo被声明为RawOptionSetType,而CGImageAlphaInfo没有。也许这与此有关?

官方的按位运算符文档并没有涵盖枚举类型,这并没有帮助。

3个回答

11

你已经拥有了等效的 Swift 代码:

bitmapInfo &= ~CGBitmapInfo.AlphaInfoMask
bitmapInfo |= CGBitmapInfo(CGImageAlphaInfo.NoneSkipFirst.rawValue)

有点奇怪,因为CGImageAlphaInfo实际上不是位掩码——它只是一个UInt32的enum(或者在C语言中使用类型为uint32_t的CF_ENUM/NS_ENUM),其值为0到7。

实际发生的是,您的第一行清除了bitmapInfo的前五位,这是一个位掩码(在Swift中称为RawOptionSetType),因为CGBitmapInfo.AlphaInfoMask为31,即0b11111。然后,您的第二行将CGImageAlphaInfo枚举的原始值插入到这些已清除的位中。

我还没有看到过将枚举和位掩码结合在一起的情况,如果这能解释为什么没有真正的文档,那就是原因。由于CGImageAlphaInfo是一个枚举,其值是互斥的。这是毫无意义的:

bitmapInfo &= ~CGBitmapInfo.AlphaInfoMask
bitmapInfo |= CGBitmapInfo(CGImageAlphaInfo.NoneSkipFirst.rawValue)
bitmapInfo |= CGBitmapInfo(CGImageAlphaInfo.PremultipliedLast.rawValue)

4
在Swift 2.0中,这又发生了变化,现在使用OptionSetTypeProtocol。现在应该使用var bitmapInfo: CGBitmapInfo = CGBitmapInfo(rawValue: ~CGBitmapInfo.AlphaInfoMask.rawValue | CGImageAlphaInfo.NoneSkipFirst.rawValue) - JackPearse

8
从Swift 3、Xcode 8 Beta 5开始,语法(如JackPearse指出的,它符合OptionSetType协议)再次发生了变化,我们不再需要使用“~CGBitmapInfo.AlphaInfoMask.rawValue”,而是直接使用。
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.last.rawValue)

你可以通过使用 | 运算符添加其他位图信息设置,例如。
let bitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo.byteOrder32Big.rawValue | CGImageAlphaInfo.first.rawValue)

1
原来,CGImageAlphaInfo的值需要转换为CGBitmapInfo才能进行按位操作。可以像这样完成此操作:
bitmapInfo &= ~CGBitmapInfo.AlphaInfoMask
bitmapInfo |= CGBitmapInfo(CGImageAlphaInfo.NoneSkipFirst.rawValue)

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