13

I'm rewriting Apple's UIImageEffects sample code from Objective-C to Swift and I have a question regarding the following line:

vImage_CGImageFormat format = {
    .bitsPerComponent = 8,
    .bitsPerPixel = 32,
    .colorSpace = NULL,
    .bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little,
    .version = 0,
    .decode = NULL,
    .renderingIntent = kCGRenderingIntentDefault
};

Here is my version in Swift:

let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue | CGBitmapInfo.ByteOrder32Little.rawValue)
let format = vImage_CGImageFormat(bitsPerComponent: 8, bitsPerPixel: 32, colorSpace: nil, bitmapInfo: bitmapInfo, version: 0, decode: nil, renderingIntent: .RenderingIntentDefault)

Is this the simplest way to create bitmapInfo in Swift?

Mahmut Ali ÖZKURAN
  • 1,120
  • 2
  • 23
  • 28
Rudolf Adamkovič
  • 31,030
  • 13
  • 103
  • 118

2 Answers2

14

You can make it a little simpler:

let bimapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue)
    .union(.ByteOrder32Little)

You unfortunately can't get away from converting the CGImageAlphaInfo into a CGBitmapInfo. That's just a weakness in the current API. But once you have it, you can use .union to combine it with other values. And once the enum type is known, you don't have to keep repeating it.

It's weird to me that there's no operator available here. I've opened a radar for that, and included an | implementation. http://www.openradar.me/23516367

public func |<T: SetAlgebraType>(lhs: T, rhs: T) -> T {
    return lhs.union(rhs)
}

@warn_unused_result
public func |=<T : SetAlgebraType>(inout lhs: T, rhs: T) {
    lhs.unionInPlace(rhs)
}

let bimapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue)
    | .ByteOrder32Little
Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • 7
    There's no operator because Swift wants you to think of these as collections (so the bit operations are kind of an implementation detail). The preferred syntax is using an array literal: `let bimapInfo: CGBitmapInfo = [ CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue), .ByteOrder32Little ]`. – Patrick Pijnappel Apr 17 '16 at 07:38
6

It’s not pretty right now no matter what you do, but I think the cleanest style (as of Swift 4) is to use something like:

let bitmapInfo: CGBitmapInfo = [
      .byteOrder32Little,
      .floatComponents,
      CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)]

(Or use something similar inline.) This at least preserves the essential optionset-iness of the info.

user1687195
  • 9,058
  • 2
  • 15
  • 15
Wil Shipley
  • 9,343
  • 35
  • 59