我正在使用此扩展来获取像素颜色:
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 值,但我有点困惑如何“恢复”“正确”值。
最佳答案
更新:
既然苹果说:
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/