Я создал, может быть, немного надуманное решение.
Сначала я создал структуру пикселей, описывающую то, что представляет собой пиксель.
struct Pixel {
var r: Float
var g: Float
var b: Float
var a: Float
var row: Int
var col: Int
init(r: UInt8, g: UInt8, b: UInt8, a: UInt8, row: Int, col: Int) {
self.r = Float(r)
self.g = Float(g)
self.b = Float(b)
self.a = Float(a)
self.row = row
self.col = col
}
var color: UIColor {
return UIColor(
red: CGFloat(r/255.0),
green: CGFloat(g/255.0),
blue: CGFloat(b/255.0),
alpha: CGFloat(a/255.0)
)
}
var description: String {
return "\(r), \(g), \(b), \(a)"
}
}
Затем я создалРасширение UIImage.
extension UIImage {
var pixelData: [Pixel] {
let bmp = self.cgImage!.dataProvider!.data
var data: UnsafePointer<UInt8> = CFDataGetBytePtr(bmp)
var r, g, b, a: UInt8
var pixels = [Pixel]()
for row in 0 ..< Int(self.size.width) {
for col in 0 ..< Int(self.size.height) {
r = data.pointee
data = data.advanced(by: 1)
g = data.pointee
data = data.advanced(by: 1)
b = data.pointee
data = data.advanced(by: 1)
a = data.pointee
data = data.advanced(by: 1)
pixels.append(Pixel(r: r, g: g, b: b, a: a, row: row, col: col))
}
}
return pixels
}
var monochrome: UIImage? {
let context = CIContext(options: nil)
// let currentFilter = CIFilter(name: "CIPhotoEffectNoir")
let currentFilter = CIFilter(name: "CIColorMonochrome")
currentFilter?.setValue(CIImage(image: self), forKey: kCIInputImageKey)
guard let output = currentFilter?.outputImage,
let cgImage = context.createCGImage(output, from: output.extent) else {
print("Failed to create output image")
return nil
}
return UIImage(cgImage: cgImage, scale: scale, orientation: imageOrientation)
}
}
Я создал монохромный фильтр, вы можете увидеть закомментированный код, вы можете использовать его для создания фильтра в оттенках серого.
После этого все, что мне нужно былосделать это проверить и проанализировать:
let image = UIImage(named: "Test2")!
let grayScale: [Bool] = image.pixelData.map {
var white: CGFloat = 0
var alpha: CGFloat = 0
$0.color.getWhite(&white, alpha: &alpha)
return white > 0.5
}
var trues = 0
var falses = 0
grayScale.forEach {
if $0 {
trues += 1
} else {
falses += 1
}
}
Последний шаг также может быть преобразован в расширение. Надеюсь, это поможет!