Подтвердить что ты не робот

CGAitmapInfo альфа-маска после swift 2.0

Я использую библиотеку из этого github repo https://github.com/Haneke/HanekeSwift для кэширования изображений, загружаемых с сервера. После обновления до версии 2.0 все испортилось.

Я смог исправить все, кроме этой функции:

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

    // See: http://stackoverflow.com/info/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/info/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)

error: Невозможно преобразовать значение типа 'CGBitmapInfo' в ожидаемый аргумент типа UInt32

4b9b3361

Ответ 1

error: Невозможно преобразовать значение типа 'CGBitmapInfo' в ожидаемый аргумент типа UInt32

Swift 2.0 фактически ожидает UInt32 вместо объекта CGBitMapInfo, поэтому вы должны вынуть переменную UInt32 в CGBitMapInfo.

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

OptionSetType В 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, его OptionSetType для OptionSetTypes

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 }
}

пример того, как инициализировать его с помощью байтового порядка и настройки альфа-маски:

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

связанный вопрос, ответ и комментарий