@@ -211,7 +211,7 @@ class Tool
211211 void quadsToTriangles ();
212212
213213 // / @brief Convert multiple image files to a mpeg movie file
214- void imgToMpeg ();
214+ void movie ();
215215
216216 // / @brief construct a LoD sequences of VDB trees with powers of two refinements
217217 void multires ();
@@ -449,13 +449,14 @@ void Tool::init()
449449 [&](){mParser .setDefaults ();}, [&](){this ->quadsToTriangles ();});
450450
451451 mParser .addAction (
452- {" img2mpeg" }, " Convert multiple images to an mpeg file" ,
453- {{" framerate" , " 24" , " 30" , " desired frame rate of mpeg movie" },
454- {" input" , " slice_*.ppm" , " input.avi" , " input image files" },
455- {" output" , " slices.mp4" , " output.mp4" , " name out output mpeg file." },
452+ {" movie" , " img2mpeg" , " mov2mpeg" , " mov2gif" , " img2gif" }, " Convert image and movie files to mpeg or animated gif files" ,
453+ {{" fps" , " 24" , " 24" , " desired frame rate of mpeg movie" },
454+ {" input" , " slice_*.ppm" , " slice_*.ppm|input.avi" , " input image files or movie file to get converted" },
455+ {" output" , " slices.mp4" , " output.mp4|output.gif" , " name of output mpeg or gif file" },
456+ {" scale" , " " , " 1280x720|640" , " scale of the output movie or gif." },
456457 {" flip" , " " , " vertical|horizontal|180" , " flip output video vertical or horizontal or rotate it by 180" },
457458 {" keep" , " true" , " 1|0|true|false" , " toggle wether the input images are preserved or deleted after the conversion" }},
458- [&](){mParser .setDefaults ();}, [&](){this ->imgToMpeg ();});
459+ [&](){mParser .setDefaults ();}, [&](){this ->movie ();});
459460
460461 mParser .addAction (
461462 {" mesh2ls" , " mesh2sdf" }, " Convert a watertight polygon surface into a narrow-band level set, i.e. a narrow-band signed distance to a polygon mesh" ,
@@ -2679,49 +2680,48 @@ void Tool::slice()
26792680
26802681// ==============================================================================================================
26812682
2682- #ifdef VDB_TOOL_USE_MPEG
26832683// / @brief Convert multiple image files to a mpeg movie file
26842684// vdb_tool -sphere -for x=0,1,0.01 -slice X='{$x}' -end -img2mpeg input="slice_*.ppm" output=slices.mp4
26852685// vdb_tool -sphere -for x=0,1,0.01 -slice X='{$x}' -end -img2mpeg && open slices.mp4
2686- void Tool::imgToMpeg ()
2686+ void Tool::movie ()
26872687{
2688- const int framerate = mParser .get <int >(" framerate" );
2688+ #ifdef VDB_TOOL_USE_MPEG
2689+ const int fps = mParser .get <int >(" fps" );
26892690 const std::string input = mParser .get <std::string>(" input" );
26902691 const std::string output = mParser .get <std::string>(" output" );
2692+ const VecI scale = mParser .getVec <int >(" scale" , " x" );
26912693 const bool keep = mParser .get <bool >(" keep" );
26922694 const std::string flip = mParser .get <std::string>(" flip" );
26932695
26942696 std::string cmd (" ffmpeg" ), log (" log.txt" );
26952697 cmd += " -loglevel error" ;// only log error messages
2696- cmd += " -pattern_type glob" ;// support expanding shell-like wildcard patterns (globbing)
2697- cmd += " -framerate " + std::to_string (framerate);// specify frame rate
2698+ if (contains (input, ' *' )) cmd += " -pattern_type glob" ;// support expanding shell-like wildcard patterns (globbing)
26982699 cmd += " -i \' " + input + " \' " ;// specify multiple input files as "input_*.ppm"
2699- if (flip==" vertical" ) {
2700- cmd += " -vf \" vflip\" " ;// flip vertical (up/down)
2701- } else if (flip==" horizontal" ) {
2702- cmd += " -vf \" hflip\" " ;// flip horizontal (left/right)
2703- } else if (flip==" 180" ) {
2704- cmd += " -vf \" vflip,hflip\" " ;// rotate 180
2705- } else if (flip!=" " ) {
2706- throw std::invalid_argument (" Tool::imgToMpeg: invalid flip argument: \" " +flip+" \" , expected \" vertical\" , \" horizontal\" or \" 180\" " );
2707- }
2700+ cmd += " -vf \" fps=" + std::to_string (fps);
2701+ if (findMatch (flip,{" vertical" , " 180" })) cmd += " ,vflip" ;// flip vertical (up/down)
2702+ if (findMatch (flip,{" horizontal" ," 180" })) cmd += " ,hflip" ;// flip horizontal (left/right)
2703+ if (flip!=" " && !contains (cmd," flip" )) throw std::invalid_argument (" Tool::movie: invalid argument flip=\" " +flip+" \" , expected \" vertical\" , \" horizontal\" or \" 180\" " );
2704+ if (scale.size ()==2 ) {
2705+ cmd += " ,scale=" + std::to_string (scale[0 ]) + " :" + std::to_string (scale[1 ]) + " :flags=lanczos" ;
2706+ } else if (scale.size ()==1 ) {
2707+ cmd += " ,scale=" + std::to_string (scale[0 ]) + " :-1:flags=lanczos" ;
2708+ }
2709+ cmd += " \" " ;// end "-vf \"fps=..."
2710+ if (getExt (output) == " gif" ) cmd += " -c:v gif" ;// create animated gif
27082711 cmd += " -y " + output;// overwrite output files without asking
27092712 cmd += " > " + log + " 2>&1" ;// redirect stdout and stderr to log file
2710-
2713+ if ( mParser . verbose ) std::cerr << cmd << std::endl;
27112714 const int code = std::system (cmd.c_str ());
27122715 if (code != 0 ) {
27132716 std::stringstream ss;
2714- ss << " \n Fatal error in Tool::imgToMpeg : " << code << " \n\" " << cmd << " \"\n " << std::ifstream (log).rdbuf ();
2717+ ss << " \n Fatal error in Tool::movie : " << code << " \n\" " << cmd << " \"\n " << std::ifstream (log).rdbuf ();
27152718 throw std::runtime_error (ss.str ());
27162719 }
27172720 std::system ((" rm " + log).c_str ());
2718- }// Tool::imgToMpeg
27192721#else
2720- void Tool::imgToMpeg ()
2721- {
27222722 throw std::runtime_error (" MPEG support was disabled during compilation!" );
2723- }// Tool::imgToMpeg
27242723#endif
2724+ }// Tool::movie
27252725
27262726// ==============================================================================================================
27272727// LeVeque, R., High-Resolution Conservative Algorithms For Advection In Incompressible Flow, SIAM J. Numer. Anal. 33, 627–665 (1996)
0 commit comments