2017-02-23 5 views
0

多くのUIImageオブジェクトを持つUIImageアレイがあり、linkに記載されている方法を使用して、イメージアレイをビデオにエクスポートします。すべてが動作しますが、CVPixelBufferからUIImage配列を変換のパフォーマンスは非常に恐ろしいです: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のような私のビデオ編集アプリケーションでは、1つの画像をビデオに変換して画像を作成する必要があります(今はビデオです)。
UIImageアレイは、本質的にUIImageからのものである。したがって、私は繰り返しnewPixelBufferFromの呼び出しを避けますが、1回だけです。次のコードは高速になります:

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 
    } 
関連する問題