Thông báo
Gần đây tôi cần thiết để viết chức năng này một lần nữa, và thấy rằng phương pháp này dường như không có tác dụng nữa (ít nhất là tôi không thể làm cho nó hoạt động trên iOS 10.3.1). Hình ảnh đầu ra sẽ không được căn chỉnh. Tôi đoán đó là do sai số bytesPerRow
.
gốc trả lời
Các bộ đệm chỉ đơn giản là một mảng pixel, do đó, bạn thực sự có thể xử lý bộ đệm trực tiếp mà không sử dụng vImage. Mã được viết bằng Swift, nhưng tôi nghĩ thật dễ dàng để tìm thấy tương đương Objective-C.
Swift 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)
Swift 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)
Nếu bạn muốn cắt từ một số vị trí cụ thể, thêm đoạn mã sau:
// calculate start position
let bytesPerPixel = 4
let startPoint = [ "x": 10, "y": 10 ]
let startAddress = baseAddress + startPoint["y"]! * bytesPerRow + startPoint["x"]! * bytesPerPixel
và thay đổi baseAddress
trong CGBitmapContextCreate
vào startAddress
. Đảm bảo không vượt quá chiều rộng và chiều cao của ảnh gốc.
Hi Sten, tôi đã tìm kiếm hướng dẫn cho một ví dụ cắt nhưng không thể tốt, bạn có thể đưa ra một ví dụ làm thế nào để cắt bộ đệm trực tiếp? – Eyal
vImage không có chức năng cắt ảnh – AlexeyVMP
Đúng là vimage không có chức năng cắt xén chuyên dụng. Nhưng bằng cách đặt kích thước của bộ đệm, bạn có thể áp dụng một loại cây trồng cùng với bất kỳ chức năng cơ bản nào, ví dụ: một quy mô. Tôi đã cập nhật câu trả lời của mình với một ví dụ – Sten