class YUVToRGBConverter {
func convertYUVToRGB(yBuffer: UnsafeMutableRawPointer, uBuffer: UnsafeMutableRawPointer, vBuffer: UnsafeMutableRawPointer, width: Int, height: Int, yStride: Int, uStride: Int, vStride: Int, rgbContext: CGContext) {
for y in 0..<height {
for x in 0..<width {
let yOffset = y * yStride + x
let uOffset = (y / 2) * uStride + (x / 2)
let vOffset = (y / 2) * vStride + (x / 2)
let yValue = Float(yBuffer.load(fromByteOffset: yOffset, as: UInt8.self))
let uValue = Float(uBuffer.load(fromByteOffset: uOffset, as: UInt8.self)) - 128
let vValue = Float(vBuffer.load(fromByteOffset: vOffset, as: UInt8.self)) - 128
var rValue = yValue + 1.402 * vValue
var gValue = yValue - 0.344 * uValue - 0.714 * vValue
var bValue = yValue + 1.772 * uValue
rValue = min(max(rValue, 0), 255)
gValue = min(max(gValue, 0), 255)
bValue = min(max(bValue, 0), 255)
rgbContext.setFillColor(red: CGFloat(rValue) / 255.0, green: CGFloat(gValue) / 255.0, blue: CGFloat(bValue) / 255.0, alpha: 1.0)
rgbContext.fill(CGRect(x: x, y: y, width: 1, height: 1))
}
}
}
}
拓展:通过YUVData识别视频帧里边的二维码
func detectQRCode(fromYUVData yBuffer: UnsafeMutableRawPointer, uBuffer: UnsafeMutableRawPointer, vBuffer: UnsafeMutableRawPointer, width: Int, height: Int, yStride: Int, uStride: Int, vStride: Int) -> String? {
guard let rgbContext = CGContext(data: nil, width: width, height: height, bitsPerComponent: 8, bytesPerRow: width * 4, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue) else {
return nil
}
let yuvToRGBConverter = YUVToRGBConverter()
yuvToRGBConverter.convertYUVToRGB(yBuffer: yBuffer, uBuffer: uBuffer, vBuffer: vBuffer, width: width, height: height, yStride: yStride, uStride: uStride, vStride: vStride, rgbContext: rgbContext)
if let cgImage = rgbContext.makeImage() {
let ciImage = CIImage(cgImage: cgImage)
let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: nil)
let features = detector?.features(in: ciImage)
for feature in features ?? [] {
if let qrCodeFeature = feature as? CIQRCodeFeature {
return qrCodeFeature.messageString
}
}
return nil
}
return nil
}