iOS图片相关处理

Swift 图片转成单通道灰度

2018-11-08  本文已影响2人  fd5657ed541e

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

上一篇 下一篇

猜你喜欢

热点阅读