QTKitPlayerにフレームを画像として保存する

QTKitPlayerで再生中の動画の、現フレームを画像として保存する方法。ここではpngに限定してる。MovieDocument.hに次のコードを追加。

- (IBAction)doSaveCurrentFrameAsImage:(id)sender
{
	NSSavePanel *savePanel;
	
	QTTime qtCurrentTime = [mMovie currentTime];
	float currentTime = qtCurrentTime.timeValue / qtCurrentTime.timeScale;
	
	NSString *baseName = [[[self fileName] lastPathComponent] stringByDeletingPathExtension];
	NSString *fileName = [NSString stringWithFormat:@"%@-%07.2f.%@", baseName, currentTime, @"png"];
	
    // init
    savePanel = [NSSavePanel savePanel];
	
    // run the export sheet
    [savePanel beginSheetForDirectory:nil file:fileName modalForWindow:mMovieWindow modalDelegate:self
					   didEndSelector:@selector(saveCurrentFrameAsImagePanelDidEnd: returnCode: contextInfo:) contextInfo:nil];
}

	- (void)saveCurrentFrameAsImagePanelDidEnd:(NSSavePanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
    if (returnCode == NSOKButton) {

		// 現在のフレームの画像をNSImageで取得
		// 本来の画像サイズで取得するためにオプションにQTMovieNaturalSizeAttributeを追加
		NSArray *keys = [NSArray arrayWithObjects:QTMovieFrameImageType, QTMovieFrameImageSize, nil];
		NSArray *objects = [NSArray arrayWithObjects:QTMovieFrameImageTypeNSImage, [mMovie attributeForKey:QTMovieNaturalSizeAttribute], nil];
		NSDictionary *attrs = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
		NSImage				*image = [(NSImage *)[mMovie frameImageAtTime:[mMovie currentTime] withAttributes:attrs error:NULL] retain];

		// 画像データの変換
		// < http://www15.plala.or.jp/NovemberKou/programming/2ndGeneration/2ndHome/ImagePanelController/createPictureData.html >
		NSBitmapImageRep	*bitmapImageRep = [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]];
		NSDictionary		*properties = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO]
																	  forKey:NSImageInterlaced];
		NSData *pngData = [bitmapImageRep representationUsingType:NSPNGFileType
													   properties:properties];
        // export
        if (![pngData writeToFile:[sheet filename] atomically:YES])
            NSRunAlertPanel(@"Error", @"Error saving current frame as image.", nil, nil, nil);
		
		[image release];
    }
}

ちなみにwindowControllerDidLoadNib:あたりで[[mMovieView window] setContentAspectRatio:contentSize];をしておけば、QTMovieViewのアスペクト比も固定されるので便利。