import Foundation func region(_ path: String) -> (avgB: Double, avgG: Double, avgR: Double, blueCount: Int, blueRuns: [(Int,Int)]) { let data = try! Data(contentsOf: URL(fileURLWithPath: path)) let pixOff = data.withUnsafeBytes { $0.load(fromByteOffset: 10, as: UInt32.self) } let w = Int(data.withUnsafeBytes { $0.load(fromByteOffset: 18, as: Int32.self) }) let hRaw = Int(data.withUnsafeBytes { $0.load(fromByteOffset: 22, as: Int32.self) }); let h = abs(hRaw) let B = Int(data.withUnsafeBytes { $0.load(fromByteOffset: 28, as: UInt16.self) })/8 let rowBytes = (B * w + 3) & ~3 var sb = 0.0, sg = 0.0, sr = 0.0, n = 0, blue = 0 var cols = [Int](repeating: 0, count: w) for y in 360...400 { let rowStart = Int(pixOff) + (hRaw > 0 ? (h-1-y) : y) * rowBytes for x in 250...460 { let i = rowStart + x * B let b = Int(data[i]), g = Int(data[i+1]), r = Int(data[i+2]) sb += Double(b); sg += Double(g); sr += Double(r); n += 1 if b > 120 && b > r + 30 && b > g + 15 && r < 160 { blue += 1; cols[x] += 1 } } } var runs: [(Int,Int)] = []; var s = -1 for x in 250...460 { if cols[x] > 2 && s < 0 { s = x } if (cols[x] <= 2 || x == 460) && s >= 0 { runs.append((s,x)); s = -1 } } return (sb/Double(n), sg/Double(n), sr/Double(n), blue, runs) } let a = region("shot.bmp") let b = region("new.bmp") print(String(format: "OLD : avgB=%.1f avgG=%.1f avgR=%.1f bluePx=%d runs=%@", a.avgB, a.avgG, a.avgR, a.blueCount, "\(a.blueRuns)")) print(String(format: "NEW : avgB=%.1f avgG=%.1f avgR=%.1f bluePx=%d runs=%@", b.avgB, b.avgG, b.avgR, b.blueCount, "\(b.blueRuns)"))