Я использую цикл for для перебора пикселей на изображении с камеры, чтобы определить процентное соотношение определенного цвета (зеленого). Изображение с камеры составляет 12 мегапикселей. Раньше скорость составляла всего лишь долю секунды, и теперь она занимает около 8 секунд на всех iPhone, которые я тестировал после обновления до Xcode 11.
func scanImageForPixels(_ image: CGImage) -> Float {
// Create the context where we'll draw the image.
let context = getContext(for: image)
// Specify the area in the context to draw in. It should be the same size as the image.
let imageWidth = image.width
let imageHeight = image.height
let imageRect = CGRect(x: 0, y: 0, width: CGFloat(imageWidth), height: CGFloat(imageHeight))
// Draw the image so the context will contain the raw image data.
context.draw(image, in: imageRect)
// Get a pointer to the raw image data.
let RGBAPointer = context.data!.assumingMemoryBound(to: UInt8.self)
// Set up the numbers used to calculate "% Green"
let totalPixels = imageWidth * imageHeight
var greenPixels = 0
// A 32-bit image will have 4 bytes per pixel: 1 byte for each component (RGBA). For example: 32bits / 8bits = 4bytes per pixel
let bytesPerPixel = image.bitsPerPixel / image.bitsPerComponent
let minRed: Int16 = 10
let minBlue: Int16 = 10
let start = Date()
for pixelIndex in 0..<totalPixels {
// move through the memory 4 bytes at a time
let offset = pixelIndex * bytesPerPixel
// change these from UInt8 to Int16 so we can do saturation/value calculations later (multiplying by 100 will make values greater than 255)
// also make them signed, so we don't have to worry about negative numbers causing errors
let red = Int16(RGBAPointer[offset])
let green = Int16(RGBAPointer[offset+1])
let blue = Int16(RGBAPointer[offset+2])
//let alpha = Int16(RGBAPointer[offset+3]) // not used
if (green - minRed) >= red && (green - minBlue) >= blue {
greenPixels += 1
}
}
let elapsed = NSDate().timeIntervalSince(start)
print(elapsed)
return Float(100 * Double(greenPixels) / Double(totalPixels))
}
Прямо сейчас цикл for завершается за 7.063616037368774 секунды. ,Я ожидал, что это будет в 10 раз быстрее в зависимости от того, когда я использовал тот же код в предыдущих версиях Xcode.