根据 RGB 值将 N 图像中的特定像素更改为 swift 中的不同 RBG 颜色

Changing specific pixels in a UIImage based on RBG values to a different RBG color in swift

我正在制作一个更改地图颜色以突出显示国家/地区的应用程序。它就像一个代码系统,一个国家会有特定的颜色,如果条件允许,该颜色将变为黄色,其余颜色将变为绿色。它类似于基于用户输入突出显示特定国家/地区的标记系统。我之前在这上面看到过 post 并且我修改了它所以它可以使用参数作为检测颜色。 https://codedump.io/share/gEsdbwFbGT3T/1/change-color-of-certain-pixels-in-a-uiimage

这里是修改后的代码:

func processPixelsInImage(inputImage: UIImage, r: UInt8, b: UInt8, g: UInt8) -> UIImage {
        let inputCGImage     = inputImage.CGImage
        let colorSpace       = CGColorSpaceCreateDeviceRGB()
        let width            = CGImageGetWidth(inputCGImage)
        let height           = CGImageGetHeight(inputCGImage)
        let bytesPerPixel    = 4
        let bitsPerComponent = 8
        let bytesPerRow      = bytesPerPixel * width
        let bitmapInfo       = CGImageAlphaInfo.PremultipliedFirst.rawValue | CGBitmapInfo.ByteOrder32Little.rawValue

        let context = CGBitmapContextCreate(nil, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo)!
        CGContextDrawImage(context, CGRectMake(0, 0, CGFloat(width), CGFloat(height)), inputCGImage)

        let pixelBuffer = UnsafeMutablePointer<UInt32>(CGBitmapContextGetData(context))

        var currentPixel = pixelBuffer

        for _ in 0 ..< Int(height) {
            for _ in 0 ..< Int(width) {
                let pixel = currentPixel.memory

                if red(pixel) == r && green(pixel) == g && blue(pixel) == b {
                    currentPixel.memory = rgba(red: 0, green: 170, blue: 0, alpha: 255)
                }
                currentPixel = currentPixel.successor()
            }
        }

        let outputCGImage = CGBitmapContextCreateImage(context)
        let outputImage = UIImage(CGImage: outputCGImage!, scale: inputImage.scale, orientation: inputImage.imageOrientation)

        return outputImage
    }

    func alpha(color: UInt32) -> UInt8 {
        return UInt8((color >> 24) & 255)
    }

    func red(color: UInt32) -> UInt8 {
        return UInt8((color >> 16) & 255)
    }

    func green(color: UInt32) -> UInt8 {
        return UInt8((color >> 8) & 255)
    }

    func blue(color: UInt32) -> UInt8 {
        return UInt8((color >> 0) & 255)
    }

    func rgba(red red: UInt8, green: UInt8, blue: UInt8, alpha: UInt8) -> UInt32 {
        return (UInt32(alpha) << 24) | (UInt32(red) << 16) | (UInt32(green) << 8) | (UInt32(blue) << 0)
    }

当我使用黑色 (0,0,0) 以外的 RGB 值时,它不会检测和更改颜色。由于数据类型不同,我不确定它与 rgb 值的普通 CG 颜色相比是否有不同的缩放比例,但我仍然不确定如何充分使用此功能。如何使用 RGB 值检测黑色以外的颜色并将其更改为其他颜色?

我调整了类似的代码以将所有 UIImage 白色像素更改为透明像素

(Swift 3)

func processPixelsInImage(_ image: UIImage) -> UIImage? {
guard let inputCGImage = image.cgImage else {
    //print("unable to get cgImage")
    return nil
}
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.draw(inputCGImage, in: CGRect(x: 0, y: 0, width: width, height: height))

guard let buffer = context.data else {
    //print("unable to get context data")
    return nil
}

let pixelBuffer = buffer.bindMemory(to: RGBA32.self, capacity: width * height)

let white = RGBA32(red: 255, green: 255, blue: 255, alpha: 255)
let clear = RGBA32(red: 0, green: 0, blue: 0, alpha: 0)

for row in 0 ..< Int(height) {
    for column in 0 ..< Int(width) {
        let offset = row * width + column
        if pixelBuffer[offset] == white {
            pixelBuffer[offset] = clear
        }
    }
}

let outputCGImage = context.makeImage()!
let outputImage = UIImage(cgImage: outputCGImage, scale: image.scale, orientation: image.imageOrientation)

return outputImage

}


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

static func ==(lhs: RGBA32, rhs: RGBA32) -> Bool {
    return lhs.color == rhs.color
}

}