注意
我最近需要重新寫這個功能,並且發現這種方法似乎不工作了(至少我無法得到它在iOS 10.3.1工作)。輸出圖像不會對齊。我猜這是因爲錯誤的bytesPerRow
。
原始回答
緩衝區是簡單的像素的陣列,所以可以實際上不使用VIMAGE直接處理該緩衝器。代碼是用Swift編寫的,但我認爲很容易找到Objective-C的等價物。
斯威夫特3
let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
CVPixelBufferLockBaseAddress(imageBuffer, .readOnly)
let baseAddress = CVPixelBufferGetBaseAddress(imageBuffer)
let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer)
let cropWidth = 640
let cropHeight = 640
let colorSpace = CGColorSpaceCreateDeviceRGB()
let context = CGContext(data: baseAddress, width: cropWidth, height: cropHeight, bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue | CGBitmapInfo.byteOrder32Little.rawValue)
CVPixelBufferUnlockBaseAddress(imageBuffer, .readOnly)
// create image
let cgImage: CGImage = context!.makeImage()!
let image = UIImage(cgImage: cgImage)
斯威夫特2
let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
CVPixelBufferLockBaseAddress(imageBuffer, 0)
let baseAddress = CVPixelBufferGetBaseAddress(imageBuffer)
let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer)
let cropWidth = 640
let cropHeight = 640
let colorSpace = CGColorSpaceCreateDeviceRGB()
let context = CGBitmapContextCreate(baseAddress, cropWidth, cropHeight, 8, bytesPerRow, colorSpace, CGImageAlphaInfo.NoneSkipFirst.rawValue | CGBitmapInfo.ByteOrder32Little.rawValue)
// create image
let cgImage: CGImageRef = CGBitmapContextCreateImage(context)!
let image = UIImage(CGImage: cgImage)
如果你想從某個特定位置剪裁,添加以下代碼:
// calculate start position
let bytesPerPixel = 4
let startPoint = [ "x": 10, "y": 10 ]
let startAddress = baseAddress + startPoint["y"]! * bytesPerRow + startPoint["x"]! * bytesPerPixel
和變化baseAddress
in CGBitmapContextCreate
into startAddress
。確保不要超過原圖像的寬度和高度。
然後,我怎樣才能將其轉換回CMSampleBuffer,或者我怎麼能寫下來使用self.videoWriterInput? – vodkhang 2011-12-14 01:36:19
任何人有任何想法? – Ondrej 2012-05-02 20:23:01
CIContext具有將CIImage柵格化爲CVPixelBuffer的方法。 – 2012-07-31 07:37:54