我想打开现有的电影文件,并将此文件的每一帧导出为JPEG或TIFF等图像。到目前为止我到目前为止:
int main(int argc, char* argv[]) {
char filename[255]; // Filename to ping.
OSErr e; // Error return.
FSSpec filespec; // QT file specification
short filemovie; // QT movie handle.
Movie movie; // QT movie "object".
InitializeQTML(0);
EnterMovies();
// Because of QT's Mac origin, must convert C-string filename
// to Pascal counted string, then use that to make a filespec.
c2pstr(filename);
FSMakeFSSpec(0, 0L, (ConstStr255Param)filename, &filespec);
OpenMovieFile(&filespec, &filemovie, fsRdPerm);
NewMovieFromFile(&movie, filemovie, nil, nil, newMovieActive, nil);
...
直到现在它工作正常(我用TimeValue movietime = GetMovieDuration(movie);
测试并打印),但现在我想获得电影的每一帧并将其导出到一个文件中(首先,后来我只想保留内存中的数据可以使用它,但我必须知道它是否真的有效,所以现在导出到图像文件更好。)
我怎么做?我需要GWorld或PixMap吗?如何从电影文件中获取GWorld / PixMap,尤其是每一帧?
编辑:我的平台是WinXP
答案 0 :(得分:1)
如果您只使用OS X,我会坚持使用QTKit API,因为它们的级别要高得多,而且通常更容易使用。
您想要做的一般要点是:
要逐步浏览QuickTime影片中的帧,您可以使用QTKit中的QTMovie类执行此操作,如下所示:
- (void)dumpFramesWithMovie:(QTMovie*)movie toFolder:(NSString*)folderPath
{
[movie setIdling:NO]; // Don't idle the movie
[movie gotoEnd];
QTTime endTime = [movie currentTime];
[movie gotoBeginning];
// Number of frames counted so far
unsigned long numFrames = 0;
// Turn off the Movie's looping so we are quaranteed to stop
[movie setAttribute:[NSNumber numberWithBool:NO] forKey:QTMovieLoopsAttribute];
// Construct a Dictionary of to use when reading frames from a movie
NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
[attributes setObject:QTMovieFrameImageTypeNSImage forKey:QTMovieFrameImageType];
while (true)
{
QTTime curTime = [movie currentTime];
if (QTTimeCompare(curTime, endTime) == NSOrderedSame)
{
// Reached end of file
break;
}
// Get the Current Frame as an NSImage
NSImage* image = [movie frameImageAtTime:curTime
withAttributes:attributes error:nil];
// Get the bitmap representation of this image
// NOTE: This code assumes the first image representation is a NSBitmapImageRep, which is true
// by default in OS X 10.5 and later.
// Production code should do error checking here.
NSBitmapImageRep *bitmap = [[image representations] objectAtIndex: 0];
// Construct a filename based upon the folder path and number of frames read so far
NSString* fileName = [NSString stringWithFormat:@"%@/frame%d.png", folderPath, numFrames];
// Get an PNG representation of this file
NSData *data = [bitmap representationUsingType: NSPNGFileType
properties: nil];
// Write to disk
[data writeToFile: fileName
atomically: NO];
// Step to the next Frame
[movie stepForward];
numFrames++;
}
[movie gotoBeginning];
}
@end
此代码已编译但尚未经过全面测试。
使用此方法的一个警告是,在OS X 10.5及更早版本中,MPEG-1文件无法正确解码。据我所知,这已经定为10.6。此外,如果正在编写Windows应用程序,则需要使用较低的Quicktime-C API。
在处理此问题时,请务必查看以下参考页:
答案 1 :(得分:1)
首先,关于电影出口商的这篇文章应该让你开始:
http://www.mactech.com/articles/mactech/Vol.16/16.05/May00QTToolkit/index.html
即使MacTech是Mac资源,所有描述的API函数也应该在QuickTime for Windows SDK中提供。
我会在找到时间后立即将一些示例代码拼凑在一起作为参考。
修改强>
有关其他信息,请参阅本书摘录:
QuickTime Toolkit - Basic Movie Playback and Media Types @ Google Books
编辑2 - 高级方法:电影出口商
如果您需要完成的只是从QuickTime影片中提取所有视频帧并将其转换为QuickTime API支持的其他格式,那么使用电影时无需采取任何低级操作出口强>
以下示例代码允许使用以编程方式调用的电影导出对话框,将QuickTime影片中的所有视频帧提取并转换为一堆JPEG文件。
只需在对话框的导出组合框中选择电影到图像序列,然后按选项选择所需的图像格式。
注1:如果您需要以非交互方式进行此操作,请告知我们。
注2:为清楚起见,省略了错误处理
#include "Movies.h"
#include "QTML.h"
#pragma comment (lib, "QTMLClient.lib")
...
int flags = createMovieFileDeleteCurFile
| showUserSettingsDialog
| movieToFileOnlyExport;
ItemCount movie_prop_count = 0;
CFStringRef cfpath = 0;
Boolean bool_true = true;
QTNewMoviePropertyElement movie_props[ 2 ];
Movie movie;
// initialize QuickTime API
InitializeQTML( 0 );
EnterMovies();
// set up Core Foundation string for source path (argv[ 1 ]) contains the full path to the MOV file to convert
cfpath = CFStringCreateWithCString( 0, argv[ 1 ], kCFStringEncodingASCII );
movie_props[movie_prop_count].propClass = kQTPropertyClass_DataLocation;
movie_props[movie_prop_count].propID = kQTDataLocationPropertyID_CFStringNativePath;
movie_props[movie_prop_count].propValueSize = sizeof(cfpath);
movie_props[movie_prop_count].propValueAddress = (void*)&cfpath;
movie_props[movie_prop_count].propStatus = 0;
++movie_prop_count;
// make Movie active
movie_props[movie_prop_count].propClass = kQTPropertyClass_NewMovieProperty;
movie_props[movie_prop_count].propID = kQTNewMoviePropertyID_Active;
movie_props[movie_prop_count].propValueSize = sizeof(bool_true);
movie_props[movie_prop_count].propValueAddress = &bool_true;
movie_props[movie_prop_count].propStatus = 0;
++movie_prop_count;
// aquire Movie for our Movie file
NewMovieFromProperties( movie_prop_count, movie_props, 0, 0, &movie );
// invoke conversion dialog
ConvertMovieToFile( movie, 0, 0, 0, 'TVOD', 0, 0, flags, 0 );
// clean up
DisposeMovie( movie );
CFRelease( cfpath );
ExitMovies();
TerminateQTML();
...
答案 2 :(得分:1)
这些命令行OSX实用程序非常擅长提取Quicktime影片的内容而无需购买QTPro:
答案 3 :(得分:0)
我通常只是将解码后的帧一个接一个地转储成二进制文件,然后使用一些YUV-Viewer来查看它们是否正常。为此,您必须知道解码帧的确切颜色格式和分辨率。如果您有RGB,那么肯定还有观众。
<强>更新强>
链接似乎不起作用。您将不得不谷歌搜索YUV查看器。或者,您可以从Elecard购买一个。