【问题标题】:CGBitmapInfo alpha mask after swift 2.0swift 2.0 后的 CGBitmapInfo alpha 掩码
【发布时间】:2015-09-17 20:51:29
【问题描述】:

我正在使用来自这个 github repo https://github.com/Haneke/HanekeSwift 的库来缓存从服务器下载的图像。更新到 swift 2.0 后,一切都搞砸了。

我已经能够修复除此功能之外的所有内容:

func hnk_decompressedImage() -> UIImage! {
    let originalImageRef = self.CGImage
    let originalBitmapInfo = CGImageGetBitmapInfo(originalImageRef)
    let alphaInfo = CGImageGetAlphaInfo(originalImageRef)

    // See: http://stackoverflow.com/questions/23723564/which-cgimagealphainfo-should-we-use
    var bitmapInfo = originalBitmapInfo
    switch (alphaInfo) {
    case .None:
        bitmapInfo &= ~CGBitmapInfo.AlphaInfoMask
        bitmapInfo |= CGBitmapInfo(rawValue: CGImageAlphaInfo.NoneSkipFirst.rawValue)
    case .PremultipliedFirst, .PremultipliedLast, .NoneSkipFirst, .NoneSkipLast:
        break
    case .Only, .Last, .First: // Unsupported
        return self
    }

    let colorSpace = CGColorSpaceCreateDeviceRGB()
    let pixelSize = CGSizeMake(self.size.width * self.scale, self.size.height * self.scale)
    if let context = CGBitmapContextCreate(nil, Int(ceil(pixelSize.width)), Int(ceil(pixelSize.height)), CGImageGetBitsPerComponent(originalImageRef), 0, colorSpace, bitmapInfo) {

        let imageRect = CGRectMake(0, 0, pixelSize.width, pixelSize.height)
        UIGraphicsPushContext(context)

        // Flip coordinate system. See: http://stackoverflow.com/questions/506622/cgcontextdrawimage-draws-image-upside-down-when-passed-uiimage-cgimage
        CGContextTranslateCTM(context, 0, pixelSize.height)
        CGContextScaleCTM(context, 1.0, -1.0)

        // UIImage and drawInRect takes into account image orientation, unlike CGContextDrawImage.
        self.drawInRect(imageRect)
        UIGraphicsPopContext()
        let decompressedImageRef = CGBitmapContextCreateImage(context)

        let scale = UIScreen.mainScreen().scale
        let image = UIImage(CGImage: decompressedImageRef, scale:scale, orientation:UIImageOrientation.Up)

        return image

    } else {
        return self
    }
}

具体来说,这是引发错误的代码行:

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

错误:一元运算符 '~' 不能应用于 CGBitmapInfo 类型的操作数

bitmapInfo |= CGBitmapInfo(rawValue: CGImageAlphaInfo.NoneSkipFirst.rawValue)

错误:二元运算符“|=”不能应用于“CGBitmapInfo”类型的操作数

if let context = CGBitmapContextCreate(nil, Int(ceil(pixelSize.width)), Int(ceil(pixelSize.height)), CGImageGetBitsPerComponent(originalImageRef), 0, colorSpace, bitmapInfo)

错误:无法将“CGBitmapInfo”类型的值转换为 UInt32 类型的预期参数

【问题讨论】:

    标签: ios swift swift2 alpha-transparency


    【解决方案1】:

    错误:无法将“CGBitmapInfo”类型的值转换为 UInt32 类型的预期参数

    Swift 2.0 实际上需要一个 UInt32 而不是 CGBitMapInfo 对象,所以你应该在 CGBitMapInfo 中取出一个 UInt32 变量。

    CGBitmapContextCreate(
        nil, 
        Int(ceil(pixelSize.width)), 
        Int(ceil(pixelSize.height)), 
        CGImageGetBitsPerComponent(originalImageRef), 
        0, 
        colorSpace, 
        bitmapInfo.rawValue)
    

    https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGBitmapContext/#//apple_ref/c/func/CGBitmapContextCreate

    【讨论】:

      【解决方案2】:

      选项集类型 在swift 2 CGBitmapInfo 是一个OptionSetType。要初始化一个,您可以遵循约定

      ///       static let Box = PackagingOptions(rawValue: 1)
      ///       static let Carton = PackagingOptions(rawValue: 2)
      ///       static let Bag = PackagingOptions(rawValue: 4)
      ///       static let Satchel = PackagingOptions(rawValue: 8)
      ///       static let BoxOrBag: PackagingOptions = [Box, Bag]
      ///       static let BoxOrCartonOrBag: PackagingOptions = [Box, Carton, Bag]
      

      在 CGBitmapInfo 的情况下,它是 OptionSetTypes 的 OptionSetType

      public enum CGImageAlphaInfo : UInt32 {
      
          case None /* For example, RGB. */
          case PremultipliedLast /* For example, premultiplied RGBA */
          case PremultipliedFirst /* For example, premultiplied ARGB */
          case Last /* For example, non-premultiplied RGBA */
          case First /* For example, non-premultiplied ARGB */
          case NoneSkipLast /* For example, RBGX. */
          case NoneSkipFirst /* For example, XRGB. */
          case Only /* No color data, alpha data only */
      }
      
      @available(iOS 2.0, *)
      public struct CGBitmapInfo : OptionSetType {
          public init(rawValue: UInt32)
      
          public static var AlphaInfoMask: CGBitmapInfo { get }
          public static var FloatComponents: CGBitmapInfo { get }
      
          public static var ByteOrderMask: CGBitmapInfo { get }
          public static var ByteOrderDefault: CGBitmapInfo { get }
          public static var ByteOrder16Little: CGBitmapInfo { get }
          public static var ByteOrder32Little: CGBitmapInfo { get }
          public static var ByteOrder16Big: CGBitmapInfo { get }
          public static var ByteOrder32Big: CGBitmapInfo { get }
      }
      

      如何使用字节顺序和 alpha 掩码设置对其进行初始化的示例:

          let bitmapInfo:CGBitmapInfo = [.ByteOrder32Little, CGBitmapInfo(rawValue: ~CGBitmapInfo.AlphaInfoMask.rawValue | CGImageAlphaInfo.PremultipliedFirst.rawValue)]
      

      related question, answer and comment

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多