// // PhotosImageClassfier+Blurry.swift // Demo // // Created by Groot on 2025/4/27. // import UIKit extension PhotosImageClassifier { static func detectBlurryImages(item: ImageItem) -> Bool { guard let image = item.thumbnailImage else { return false } return isImageBlurry(image) } private static func isImageBlurry(_ image: UIImage) -> Bool { guard let cgImage = image.cgImage else { return false } // 使用更小的采样区域 let width = cgImage.width let height = cgImage.height let pixelStride = 4 // 改名为pixelStride,避免与函数名冲突 // 提前检查图像尺寸是否合法 guard width > (2 * pixelStride), height > (2 * pixelStride) else { return false } // 使用vImage进行快速处理 var buffer = [UInt8](repeating: 0, count: width * height) let colorSpace = CGColorSpaceCreateDeviceGray() guard let context = CGContext( data: &buffer, width: width, height: height, bitsPerComponent: 8, bytesPerRow: width, space: colorSpace, bitmapInfo: CGImageAlphaInfo.none.rawValue ) else { return false } context.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height)) // 使用拉普拉斯算子的简化版本 var score: Double = 0 var sampledPixels = 0 // 只采样图像的一部分区域 let sampleRows = 10 let sampleCols = 10 // 计算步长 let rowStep = max(1, height / sampleRows) let colStep = max(1, width / sampleCols) // 使用Swift的stride函数 for y in Swift.stride(from: pixelStride, to: height - pixelStride, by: rowStep) { for x in Swift.stride(from: pixelStride, to: width - pixelStride, by: colStep) { let current = Int(buffer[y * width + x]) let left = Int(buffer[y * width + (x - pixelStride)]) let right = Int(buffer[y * width + (x + pixelStride)]) let top = Int(buffer[(y - pixelStride) * width + x]) let bottom = Int(buffer[(y + pixelStride) * width + x]) // 简化的边缘检测 let dx = abs(left - right) let dy = abs(top - bottom) score += Double(max(dx, dy)) sampledPixels += 1 } } // 避免除以零 guard sampledPixels > 0 else { return false } // 归一化分数 let normalizedScore = score / Double(sampledPixels) // 调整阈值 let threshold = 15.0 return normalizedScore < threshold } }