5

i am making an app in Swift (i have the last xcode update) that has to generate a video from some images.
I got the code from this answer How do I export UIImage array as a movie?
I call the function like this:

let size = CGSize(width: 1280, height: 720)
let pathVideo = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let percorsoVideo = pathVideo[0]
writeImagesAsMovie(arrayImmagini, videoPath: percorsoVideo+"/prova.mp4", videoSize: size, videoFPS: 1)

"arrayImmagini" is defined literally like this:

var arrayImmagini = [UIImage(imageLiteral: "Frames/turtle/turtle0.jpg"), UIImage(imageLiteral: "Frames/turtle/turtle1.jpg"), ...]

When i try to run the code i get a completely black video and xcode gives me this 2 errors as many times as many images there are in the array:

Sep  5 09:24:15  Prova[1554] <Error>: CGBitmapContextCreate: invalid data bytes/row: should be at least 7680 for 8 integer bits/component, 3 components, kCGImageAlphaPremultipliedFirst.
Sep  5 09:24:15  Prova[1554] <Error>: CGContextDrawImage: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.

Reading the documentation about CGBitmapContextCreate, i tried to call it differently:

func fillPixelBufferFromImage(image: UIImage, pixelBuffer: CVPixelBufferRef) {
    CVPixelBufferLockBaseAddress(pixelBuffer, 0)

    let pixelData = CVPixelBufferGetBaseAddress(pixelBuffer)
    let rgbColorSpace = CGColorSpaceCreateDeviceRGB()

    // Create CGBitmapContext
    let context = CGBitmapContextCreate(
        nil,
        Int(image.size.width),
        Int(image.size.height),
        8,
        0,
        rgbColorSpace,
        CGImageAlphaInfo.PremultipliedFirst.rawValue
    )

    // Draw image into context
    CGContextDrawImage(context, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage)

    CVPixelBufferUnlockBaseAddress(pixelBuffer, 0)
}

Instead of:

func fillPixelBufferFromImage(image: UIImage, pixelBuffer: CVPixelBufferRef) {
    CVPixelBufferLockBaseAddress(pixelBuffer, 0)

    let pixelData = CVPixelBufferGetBaseAddress(pixelBuffer)
    let rgbColorSpace = CGColorSpaceCreateDeviceRGB()

    // Create CGBitmapContext
    let context = CGBitmapContextCreate(
        pixelData,
        Int(image.size.width),
        Int(image.size.height),
        8,
        CVPixelBufferGetBytesPerRow(pixelBuffer),
        rgbColorSpace,
        CGImageAlphaInfo.PremultipliedFirst.rawValue
    )

    // Draw image into context
    CGContextDrawImage(context, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage)

    CVPixelBufferUnlockBaseAddress(pixelBuffer, 0)
}

This made xcode stop giving me errors but i still get a black video.
Please help me, i'm new to app development and even newer to AVFoundation, i don't have any clues about how to solve it by myself.

Thank you!

Community
  • 1
  • 1
Francesco Scotti
  • 176
  • 3
  • 15

1 Answers1

3

After many attempts to make this work i found out what the problem was. You can't give a video size more little than the pictures' size.
Once i did this, everything worked:

let size = CGSize(width: 1920, height: 1280)
Francesco Scotti
  • 176
  • 3
  • 15
  • Guys, i built my application that takes some images and a music file and then convert them to video. But the images don't have cool animations. They just show and disappear. I want to apply animations to them. I have done a little research about CALayer class but i found nothing about adding animations to video in it. Can any body help me so that i can add desired animations to individual photos. That will be great. Thanks – Tech Labs Mar 09 '17 at 14:57