Diashow aus Bildern mit ffmpeg in Video umwandeln

Sa, 26.12.2009 - 11:17 -- admin

Möchte man aus mehreren Bilder z.B. aus einer flickr Bildersuche eine Diashow als Video erstellen, so kann man das wunderbar mit ein paar PHP-Zeilen und ffmpeg bewerkstelligen. Dazu müssen alle Bilder nummeriert in einem Ordner liegen und die gleiche Größe haben. Dazu lädt man die Bilder in der gewünschten Auflösung runter, verkleinert/vergrößert sie und legt hinter den Bilder einen schwarzen Hintergrund in der gewünschten Videoauflösung ab.

ffmpeg Optionen

Mit ffmpeg können durch anpassen einiger Parameter die Diashowoptionen beeinflusst werden. Neben dem Videocodec (-vcodec) und der Bitrate (-b 2048k) ist sicherlich die Framerate (-r 25) und der Paramter -r am Anfang entscheidend. Hierdurch kann man die Anzeigedauer jedes Bild definieren. Hier sind es ca. 3 Sekunden.
Darüberhinaus definiert man über den Parameter -i, welche Bilder genutzt werden sollen. Entspricht kein Bild der Relation so wird ein Fehler ausgegeben.
pics%03d.jpg = pics001.jpg, pics002.jpg, ...

ffmpeg -r 0.3 -f image2 -i bilder/pics%03d.jpg -r 25 -b 2048k -vcodec mpeg1video video.mpg

flickr Bilder mit PHP

$cfg['ffmpeg_lib']='/mnt/hdd/www/ffmpeg.static';
$cfg['output_file']='pics%03d.jpg';
$cfg['output_subdir']='output/';
$cfg['output_dir']=dirname($_SERVER['SCRIPT_FILENAME']).'/'.$cfg['output_subdir'];
$cfg['output_vid']='/mnt/hdd/www/test1.mpg';
 
require_once("phpFlickr.php");
require_once("resizeimage.php");
 
$f = new phpFlickr("<flickr api code>");
$f->enableCache("fs", "cache");
 
$photos_red = $f->photos_search(array('tags'=>'red', 'sort'=>'interestingness-desc', 'per_page'=>50));
$i=0;
 
foreach($photos_red['photo'] as $photo) {
	$url=$f->buildPhotoURL($photo, 'medium');
 
	$img=resizeImage($url,352,288);
	$img=createBorder($img,352,288);
 
	imagejpeg($img, $cfg['output_subdir'].sprintf($cfg['output_file'],$i++) ,80);
 
}
 
$ffmpeg=$cfg['ffmpeg_lib'] . ' -r 0.3 -f image2 -i '. $cfg['output_dir'].$cfg['output_file'] .' -r 25 -b 2048k -vcodec mpeg1video '. $cfg['output_vid'];
$tmp = exec($ffmpeg, $results); 

resizeimage.php

Damit ffmpeg aus mehreren Bildern eine Diashow erstellen kann, müssen alle Bilder exakt die gleiche Pixelgröße habe. Dazu sind die Funktionen resizeImage und createBorder nötig. Die Funktionen stammen original von dieser Seite. Ich habe die Hintergrundfarbe des "zweiten" Bild auf schwarz abgeändert.

/*------------------------------------------------------------------------------------------
     Micro Image Manipulation Pack
 
     ©PhpToys 2006
     http://www.phptoys.com
 
     Released under the terms and conditions of the
     GNU General Public License (http://gnu.org).
 
     $Revision: 1.0 $
     $Date: 2006/07/03 $
     $Author: PhpToys $
 
     USAGE:
          This package has 3 function to manipulta jpeg images with php code.
          - resizeImage : needs a filename and a width, height values.
          - dropShadow  : needs an image as image resource and not as filename, and you can define 
                          the shadow size.
          - createBorder: needs an image as image resource and not as filename, and the border 
                          width and height values.
--------------------------------------------------------------------------------------------*/
function resizeImage($originalImage,$toWidth,$toHeight){
 
    // Get the original geometry and calculate scales
    list($width, $height) = getimagesize($originalImage);
    $xscale=$width/$toWidth;
    $yscale=$height/$toHeight;
 
    // Recalculate new size with default ratio
    if ($yscale>$xscale){
        $new_width = round($width * (1/$yscale));
        $new_height = round($height * (1/$yscale));
    }
    else {
        $new_width = round($width * (1/$xscale));
        $new_height = round($height * (1/$xscale));
    }
 
    // Resize the original image
    $imageResized = imagecreatetruecolor($new_width, $new_height);
    $imageTmp     = imagecreatefromjpeg ($originalImage);
    imagecopyresampled($imageResized, $imageTmp, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
 
    return $imageResized;
}
 
function createBorder($img,$x,$y){
 
    // Create image base 
    $image           = imagecreatetruecolor($x,$y);
    $backgroundColor = imagecolorallocate($image,0,0,0);
    $borderColor     = imagecolorallocate($image,50,50,50);
 
    imagefill($image,0,0,$backgroundColor);
    imagerectangle($image,0,0,$x-1,$y-1, $borderColor);
 
    $width  = imagesx($img);
    $height = imagesy($img);
 
    imagecopymerge($image,$img,($x-$width)/2,($y-$height)/2,0,0,$width,$height,100);
 
    return $image;
}
 
 
function dropShadow($img,$shadowSize=5){
 
  // Set the new image size  
  $width  = imagesx($img)+$shadowSize;
  $height = imagesy($img)+$shadowSize;
 
  $image = imagecreatetruecolor(imagesx($img)+$shadowSize, imagesy($img)+$shadowSize);
 
  for ($i = 0; $i < 10; $i++){
    $colors[$i] = imagecolorallocate($image,255-($i*25),255-($i*25),255-($i*25));
  }
 
  // Create a new image
  imagefilledrectangle($image, 0,0, $width, $height, $colors[0]);
 
  // Add the shadow effect
  for ($i = 0; $i < count($colors); $i++) {
    imagefilledrectangle($image, $shadowSize, $shadowSize, $width--, $height--, $colors[$i]);
  }
 
  // Merge with the original image
  imagecopymerge($image, $img, 0,0, 0,0, imagesx($img), imagesy($img), 100);
 
  return $image;
}

Disqus - noscript

mal nen komische frage was mache ich wenn de datein : 000DC1D549DE()_1_20110425202657_3024.jpg
aussehen ??

kommt von meiner cam ?
gruss tom