extension UIImage {
func graySacled() -> UIImage? {
guard
let cgImage = cgImage,
let data = cgImage.dataProvider?.data as Data? else {
return nil
}
let width = cgImage.width
let height = cgImage.height
let channels = 4
let size = data.count / channels
let buffer = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: size)
defer { free(buffer) }
stride(from: 0, to: data.count, by: channels).forEach {
/// 这里灰色使用最简单的算法 `G = (R + G + B) / 3`
buffer.advanced(by: $0 / channels).pointee = avarage(($0..<$0 + 3).map { data[$0].uint16 }).uint8
}
/// =================== buffer 已经是`单通道` `灰色`, 下面是合成图片 ===================
let releaseData: CGDataProviderReleaseDataCallback = {
(info, buffer, length) in
}
return CGDataProvider(
dataInfo: nil,
data: buffer,
size: size,
releaseData: releaseData)
.flatMap {
CGImage(
width: width,
height: height,
bitsPerComponent: 8,
bitsPerPixel: 8,
bytesPerRow: width,
space: CGColorSpaceCreateDeviceGray(),
bitmapInfo: CGBitmapInfo(rawValue: 0),
provider: $0,
decode: nil,
shouldInterpolate: true,
intent: .defaultIntent)
}
.flatMap(UIImage.init)
}
}
public func avarage<S: Collection>(
_ sequence: S)
-> S.Element where S.Element: FixedWidthInteger {
return sequence.reduce(0, +) / S.Element(sequence.count)
}
extension UInt16 {
var uint8: UInt8 {
return UInt8(self)
}
}
extension UInt8 {
var uint16: UInt16 {
return UInt16(self)
}
}
网友评论