Getting a Black and White UIImage (Not Grayscale)

前端 未结 6 1690
独厮守ぢ
独厮守ぢ 2021-02-04 20:23

I need to get a pure black and white UIImage from another UIImage (not grayscale). Anyone can help me?

Thanks for reading.

EDITED:

Here

6条回答
  •  [愿得一人]
    2021-02-04 20:58

    Here's a swift 3 solution:

    class func pureBlackAndWhiteImage(_ inputImage: UIImage) -> UIImage? {
    
        guard let inputCGImage = inputImage.cgImage, let context = getImageContext(for: inputCGImage), let data = context.data else { return nil }
    
        let white = RGBA32(red: 255, green: 255, blue: 255, alpha: 255)
        let black = RGBA32(red: 0, green: 0, blue: 0, alpha: 255)
    
        let width = Int(inputCGImage.width)
        let height = Int(inputCGImage.height)
        let pixelBuffer = data.bindMemory(to: RGBA32.self, capacity: width * height)
    
        for x in 0 ..< height {
            for y in 0 ..< width {
                let offset = x * width + y
                if pixelBuffer[offset].red > 0 || pixelBuffer[offset].green > 0 || pixelBuffer[offset].blue > 0 {
                    pixelBuffer[offset] = black
                } else {
                    pixelBuffer[offset] = white
                }
            }
        }
    
        let outputCGImage = context.makeImage()
        let outputImage = UIImage(cgImage: outputCGImage!, scale: inputImage.scale, orientation: inputImage.imageOrientation)
    
        return outputImage
    }
    
    class func getImageContext(for inputCGImage: CGImage) ->CGContext? {
    
        let colorSpace       = CGColorSpaceCreateDeviceRGB()
        let width            = inputCGImage.width
        let height           = inputCGImage.height
        let bytesPerPixel    = 4
        let bitsPerComponent = 8
        let bytesPerRow      = bytesPerPixel * width
        let bitmapInfo       = RGBA32.bitmapInfo
    
        guard let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo) else {
            print("unable to create context")
            return nil
        }
    
        context.setBlendMode(.copy)
        context.draw(inputCGImage, in: CGRect(x: 0, y: 0, width: CGFloat(width), height: CGFloat(height)))
    
        return context
    }
    
    struct RGBA32: Equatable {
        var color: UInt32
    
        var red: UInt8 {
            return UInt8((color >> 24) & 255)
        }
    
        var green: UInt8 {
            return UInt8((color >> 16) & 255)
        }
    
        var blue: UInt8 {
            return UInt8((color >> 8) & 255)
        }
    
        var alpha: UInt8 {
            return UInt8((color >> 0) & 255)
        }
    
        init(red: UInt8, green: UInt8, blue: UInt8, alpha: UInt8) {
            color = (UInt32(red) << 24) | (UInt32(green) << 16) | (UInt32(blue) << 8) | (UInt32(alpha) << 0)
        }
    
        static let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrder32Little.rawValue
    }
    
    func ==(lhs: RGBA32, rhs: RGBA32) -> Bool {
        return lhs.color == rhs.color
    }
    

提交回复
热议问题