我正在使用此扩展名来获取像素颜色:

extension UIImage {
    subscript (x: Int, y: Int) -> UIColor? {
        guard x >= 0 && x < Int(size.width) && y >= 0 && y < Int(size.height),
            let cgImage = cgImage,
            let provider = cgImage.dataProvider,
            let providerData = provider.data,
            let data = CFDataGetBytePtr(providerData) else {
            return nil
        }

        let numberOfComponents = 4
        let pixelData = ((Int(size.width) * y) + x) * numberOfComponents

        let r = CGFloat(data[pixelData]) / 255.0
        let g = CGFloat(data[pixelData + 1]) / 255.0
        let b = CGFloat(data[pixelData + 2]) / 255.0
        let a = CGFloat(data[pixelData + 3]) / 255.0

        return UIColor(red: r, green: g, blue: b, alpha: a)
    }
}



使用操场或模拟器运行时,一切正常,但是在设备(iPhone XR)上运行时,我得到了不同的值。

经过一段时间的调试,我发现当我使用模拟器时,cgimage具有alphaInfo kCGImageAlphaLast,而当我使用设备时,alphaInfo是kCGImageAlphaNoneSkipLast

调试:

// Simulator
<CGImage 0x7f9f674150f0> (IP)
    <<CGColorSpace 0x600002893120> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; sRGB IEC61966-2.1)>
        width = 1000, height = 500, bpc = 8, bpp = 32, row bytes = 4000
        kCGImageAlphaLast | 0 (default byte order)  | kCGImagePixelFormatPacked
        is mask? No, has masking color? No, has soft mask? No, has matte? No, should interpolate? Yes
// -------------------------------------------- //

// Device
<CGImage 0x7f88df70d980> (DP)
    <<CGColorSpace 0x6000003dc540> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; sRGB IEC61966-2.1)>
        width = 1000, height = 500, bpc = 8, bpp = 32, row bytes = 4000
        kCGImageAlphaNoneSkipLast | 0 (default byte order)  | kCGImagePixelFormatPacked
        is mask? No, has masking color? No, has soft mask? No, has matte? No, should interpolate? Yes


由于alphaInfo是只读属性,因此有任何方法可以设置该属性或重新创建将alphaValue设置为kCGImageAlphaLast的方法。

我发现该颜色值乘以alpha值,但是我有点困惑如何“恢复”“正确”值。

https://developer.apple.com/documentation/coregraphics/cgimagealphainfo/kcgimagealphapremultipliedlast

最佳答案

您需要创建一个不透明的图像上下文,设置其alpha值并将原始图像绘制到此新上下文中:

extension UIImage {
    func applying(alpha: CGFloat) -> UIImage? {
        guard let cgImage = self.cgImage else { return nil }
        // For iOS10 or later you can use UIGraphicsImageRenderer
        if #available(iOS 10, *) {
            let format = imageRendererFormat
            format.opaque = false
            return UIGraphicsImageRenderer(size: size, format: format).image { context in
                context.cgContext.scaleBy(x: 1, y: -1)
                context.cgContext.translateBy(x: .zero, y: -size.height)
                context.cgContext.setBlendMode(.multiply)
                context.cgContext.setAlpha(alpha)
                context.cgContext.draw(cgImage, in: .init(origin: .zero, size: size))
            }
        } else {
            // For older iOS versions you need to use UIGraphicsBeginImageContextWithOptions
            UIGraphicsBeginImageContextWithOptions(size, false, scale)
            defer { UIGraphicsEndImageContext() }
            guard let context = UIGraphicsGetCurrentContext() else { return nil }
            context.scaleBy(x: 1, y: -1)
            context.translateBy(x: .zero, y: -size.height)
            context.setBlendMode(.multiply)
            context.setAlpha(alpha)
            context.draw(cgImage, in: .init(origin: .zero, size: size))
            return UIGraphicsGetImageFromCurrentImageContext()
        }
    }
}




let image = UIImage(data: try! Data(contentsOf: URL(string:"http://i.stack.imgur.com/Xs4RX.jpg")!))!
let transparentImage = image.applying(alpha: 0.5)


ios - 如何在CGImage上设置/更改alphaInfo?-LMLPHP

09-27 22:20