2017-02-23 25 views
0

У меня есть массив UIImage с большим количеством объектов UIImage и используйте методы, указанные link, для экспорта массива изображений в видео. Все работает, но производительность преобразования UIImage массива CVPixelBuffer очень страшно:Как повысить производительность преобразования UIImage в CVPixelBuffer?

private func newPixelBufferFrom(cgImage:CGImage) -> CVPixelBuffer?{ 
    let options:[String: Any] = [kCVPixelBufferCGImageCompatibilityKey as String: true, kCVPixelBufferCGBitmapContextCompatibilityKey as String: true] 
    var pxbuffer:CVPixelBuffer? 
    let frameWidth = self.videoSettings[AVVideoWidthKey] as! Int 
    let frameHeight = self.videoSettings[AVVideoHeightKey] as! Int 

    let status = CVPixelBufferCreate(kCFAllocatorDefault, frameWidth, frameHeight, kCVPixelFormatType_32ARGB, options as CFDictionary?, &pxbuffer) 
    assert(status == kCVReturnSuccess && pxbuffer != nil, "newPixelBuffer failed") 


    CVPixelBufferLockBaseAddress(pxbuffer!, CVPixelBufferLockFlags(rawValue: 0)) 
    let pxdata = CVPixelBufferGetBaseAddress(pxbuffer!) 
    let rgbColorSpace = CGColorSpaceCreateDeviceRGB() 
    let context = CGContext(data: pxdata, width: frameWidth, height: frameHeight, bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(pxbuffer!), space: rgbColorSpace, bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue) 
    assert(context != nil, "context is nil") 

    context!.concatenate(CGAffineTransform.identity) 
    context!.draw(cgImage, in: CGRect(x: 0, y: 0, width: frameWidth, height: frameHeight)) 
    CVPixelBufferUnlockBaseAddress(pxbuffer!, CVPixelBufferLockFlags(rawValue: 0)) 
    return pxbuffer 
} 

enter image description here Не могли бы вы дать мне некоторые идеи?
Спасибо!

ответ

0

Я решил свою проблему.
В моем приложении для редактирования видео, например iMovie, мне нужно преобразовать одно изображение в видео и сделать изображение (теперь это видео) подвижным.
A UIImage массив от UIImage по существу. Поэтому я избегаю повторного вызова newPixelBufferFrom, но только один раз. следующие коды будут выполняться быстрее:

var sampleBuffer:CVPixelBuffer? 
    var pxDataBuffer:CVPixelBuffer? 

    let options:[String: Any] = [kCVPixelBufferCGImageCompatibilityKey as String: true, kCVPixelBufferCGBitmapContextCompatibilityKey as String: true] 
    let frameHeight = self.videoSettings[AVVideoHeightKey] as! Int 
    let frameWidth = self.videoSettings[AVVideoWidthKey] as! Int 
    let originHeight = frameWidth * img!.cgImage!.height/img!.cgImage!.width 
    let heightDifference = originHeight - frameHeight 

    let frameCounts = self.duration * Int(self.frameTime.timescale) 
    let spacingOfHeight = heightDifference/frameCounts 

    sampleBuffer = self.newPixelBufferFrom(cgImage: img!.cgImage!) 
    assert(sampleBuffer != nil) 

    var presentTime = CMTimeMake(1, self.frameTime.timescale) 
    var stepRows = 0 

    for i in 0..<frameCounts { 
     CVPixelBufferLockBaseAddress(sampleBuffer!, CVPixelBufferLockFlags(rawValue: 0)) 
     let pointer = CVPixelBufferGetBaseAddress(sampleBuffer!) 
     var pxData = pointer?.assumingMemoryBound(to: UInt8.self) 
     let bytes = CVPixelBufferGetBytesPerRow(sampleBuffer!) * stepRows 
     pxData = pxData?.advanced(by: bytes) 

     let status = CVPixelBufferCreateWithBytes(kCFAllocatorDefault, frameWidth, frameHeight, kCVPixelFormatType_32ARGB, pxData!, CVPixelBufferGetBytesPerRow(sampleBuffer!), nil, nil, options as CFDictionary?, &pxDataBuffer) 
     assert(status == kCVReturnSuccess && pxDataBuffer != nil, "newPixelBuffer failed") 
     CVPixelBufferUnlockBaseAddress(sampleBuffer!, CVPixelBufferLockFlags(rawValue: 0)) 

     while !self.writeInput.isReadyForMoreMediaData { 
      usleep(100) 
     } 
     if (self.writeInput.isReadyForMoreMediaData){ 
      if i == 0{ 
       self.bufferAdapter.append(pxDataBuffer!, withPresentationTime: zeroTime) 
      }else{ 
       self.bufferAdapter.append(pxDataBuffer!, withPresentationTime: presentTime) 
      } 
      presentTime = CMTimeAdd(presentTime, self.frameTime) 
     } 

     stepRows += spacingOfHeight 
    }