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

标签 ios swift core-graphics core-image

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

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

当我使用 Playground 或模拟器运行时,一切正常,但当我在我的设备 (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

最佳答案

更新:

既然苹果说:

kCGImageAlphaPremultipliedLast

alpha 分量存储在每个像素的最低有效位中,并且颜色分量已乘以该 alpha 值。例如,预乘 RGBA。

它非常容易修复,你的 RGB 值乘以 alpha 值,所以,你只需要恢复它。

premultiplied.R = (straight.R * straight.A / 255);
premultiplied.G = (straight.G * straight.A / 255);
premultiplied.B = (straight.B * straight.A / 255);
premultiplied.A = straight.A;

所以,我们只需要做相反的事情:

straight.R = (premultiplied.R / straight.A) * 255;
straight.G = (premultiplied.G / straight.A) * 255;
straight.B = (premultiplied.B / straight.A) * 255;
straight.A = premultiplied.A;

我创建此扩展程序是为了获取像素的正确颜色:

extension UIColor {

    func rgb(alphaInfo: CGImageAlphaInfo) -> (red: UInt8, green: UInt8, blue: UInt8, alpha: UInt8) {

        var fRed : CGFloat = 0
        var fGreen : CGFloat = 0
        var fBlue : CGFloat = 0
        var fAlpha: CGFloat = 0

        if self.getRed(&fRed, green: &fGreen, blue: &fBlue, alpha: &fAlpha) {

            var iRed = fRed * 255.0
            var iGreen = fGreen * 255.0
            var iBlue = fBlue * 255.0
            let iAlpha = fAlpha * 255.0

            switch alphaInfo {
            case .premultipliedLast, .premultipliedFirst:
                iRed = (iRed / iAlpha) * 255
                iGreen = (iGreen / iAlpha) * 255
                iBlue = (iBlue / iAlpha) * 255
            default:
                break
            }

             return (red:UInt8(iRed.rounded()),
green:UInt8(iBlue.rounded()), 
blue:UInt8(iGreen.rounded()), 
alpha:UInt8(iAlpha.rounded()))
        } else {
            // Could not extract RGBA components:
            return (0, 0, 0 , 0)
        }
    }
}

关于ios - 如何设置/更改 CGImage 上的 alphaInfo?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60197882/

相关文章:

ios - 如何在单元格中调用图像 url 和 ImageView 以获取 Collection View 的索引路径功能

ios - 为什么 Alamofire 的上传进度在上传期间从未达到 1.0 的完成?

ios - 如何根据具有自动调整大小的传入数据在 Collection View 单元格中添加随机内容(UIKit 元素)?

ios - 用对角线绘制的 UIView 填充?

ios - 在 Swift 中将 float 转换为 little endian

ios - 如何从字符串中删除特殊字符\u{e2}

ios - 约束让我摸索

ios - 根据角色显示不同的view controller-Firebase, Swift 3

cocoa-touch - 带有核心图形绘图的核心动画

ios - 确定 UIGraphicsBeginImageContext 使用 CGBitmapContextCreate 创建图形上下文吗?