How can I create a Quicktime movie from a series of generated images?
I need to create a movie from a series of generated images. (I'm creating the images based on the output of a physics modeling program.)
I found Apple's sample in QtKitCreateMovie and used that as a starting point. Instead of loading jpgs from the application bundle, I'm drawing to an NSImage and then adding that NSImage to the movie object. Here's the basic code I used for testing. mMovie
is an instance of QTMovie
:
NSImage *anImage = [[NSImage alloc] initWithSize:NSMakeSize(frameSize, frameSize)];
[anImage lockFocus];
float blendValue;
for (blendValue = 0.0; blendValue <= 1.0; blendValue += 0.05) {
[[[NSColor blueColor] blendedColorWithFraction:blendValue ofColor:[NSColor redColor]] setFill];
[NSBezierPath fillRect:NSMakeRect(0, 0, frameSize, frameSize)];
[mMovie addImage:anImage forDuration:duration withAttributes:myDict];
}
[anImage unlockFocus];
[anImage release];
This works under OS X 10.5, but under OS X 10.6 I get an array index beyond bounds exception on the call to addImage:forDuration:withAttributes
: (http://openradar.appspot.com/radar?id=1146401)
What's the proper way to create a movie under 10.6?
Also, although this works under 10.5, I run out of memory if I try to create a movie 开发者_运维百科with thousands of frames. That also makes me think I'm not using the correct approach.
You're doing it right, but you're doing it wrong.
The correct way hasn't changed in QTKit. Your mistake is that you're trying to add the image before you have finished it, which happens when you unlock focus. Since you don't unlock focus until after you try to add the image (20 times), you are trying to add an unfinished image (20 times), which doesn't work.
The “out of bounds” exception is because the image has no representations. QTMovie, it seems, is trying to loop through the array returned by the image in response to a representations
message, but that array is empty because the image is not finished.
Somehow, you got away with this in Leopard (probably due to an implementation detail that changed in Snow Leopard), but I'd say it was no less your bug then.
The solution is simply to lock focus and unlock focus on the image each time through the loop:
float blendValue;
for (blendValue = 0.0; blendValue <= 1.0; blendValue += 0.05) {
[anImage lockFocus];
[[NSGraphicsContext currentContext] setShouldAntialias:NO];
[[[NSColor blueColor] blendedColorWithFraction:blendValue ofColor:[NSColor redColor]] setFill];
[NSBezierPath fillRect:NSMakeRect(0, 0, frameSize, frameSize)];
[anImage unlockFocus];
[mMovie addImage:anImage forDuration:duration withAttributes:myDict];
}
精彩评论