So I have a class that does the selection but what I get back is a total mess. Can anyone help me with the code or possibly point me at an example class that performs a magic wand selection like in photoshop? Below is my current Code but I've also attempted to use metal and I've gotten an identical result in the same amount of time
var red1: CGFloat = 0
var green1: CGFloat = 0
var blue1: CGFloat = 0
var alpha1: CGFloat = 0
selectedColor.getRed(&red1, green: &green1, blue: &blue1, alpha: &alpha1)
var red2: CGFloat = 0
var green2: CGFloat = 0
var blue2: CGFloat = 0
var alpha2: CGFloat = 0
pixelColor.getRed(&red2, green: &green2, blue: &blue2, alpha: &alpha2)
let tolerance = CGFloat(tolerance)
return abs(red1 - red2) < tolerance && abs(green1 - green2) < tolerance &&
abs(blue1 - blue2) < tolerance && abs(alpha1 - alpha2) < tolerance
}
func getPixelData(from image: UIImage) -> [UInt8]? {
guard let cgImage = image.cgImage else { return nil }
let width = Int(cgImage.width)
let height = Int(cgImage.height)
let bytesPerPixel = 4
let bytesPerRow = bytesPerPixel * width
let bitsPerComponent = 8
let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue
var pixelData = [UInt8](repeating: 0, count: width * height * bytesPerPixel)
guard let context = CGContext(data: &pixelData,
width: width,
height: height,
bitsPerComponent: bitsPerComponent,
bytesPerRow: bytesPerRow,
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: bitmapInfo) else { return nil }
context.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))
return pixelData
}
func performMagicWandSelection(inputImage: UIImage, selectedColor: UIColor, tolerance: Float) -> UIBezierPath? {
guard let pixelData = getPixelData(from: inputImage) else { return nil }
let width = Int(inputImage.size.width)
let height = Int(inputImage.size.height)
let bytesPerPixel = 4
let path = UIBezierPath()
var isDrawing = false
for y in 0..<height {
for x in 0..<width {
let index = (y * width + x) * bytesPerPixel
let pixelColor = UIColor(
red: CGFloat(pixelData[index]) / 255.0,
green: CGFloat(pixelData[index + 1]) / 255.0,
blue: CGFloat(pixelData[index + 2]) / 255.0,
alpha: CGFloat(pixelData[index + 3]) / 255.0)
if colorMatches(selectedColor: selectedColor, pixelColor: pixelColor, tolerance: tolerance) {
let point = CGPoint(x: x, y: y)
if !isDrawing {
path.move(to: point)
isDrawing = true
} else {
path.addLine(to: point)
}
} else {
if isDrawing {
path.close()
isDrawing = false
}
}
}
}
if isDrawing {
path.close()
}
return path
}