PHP Classes

File: src/PHPVideoToolkit/AnimatedGifTranscoderGifsicle.php

Recommend this page to a friend!
  Classes of Oliver Lillie   PHP Video Toolkit   src/PHPVideoToolkit/AnimatedGifTranscoderGifsicle.php   Download  
File: src/PHPVideoToolkit/AnimatedGifTranscoderGifsicle.php
Role: Class source
Content type: text/plain
Description: Class source
Class: PHP Video Toolkit
Manipulate and convert videos with ffmpeg program
Author: By
Last change: Some Fixes
- Corrected some PHPDoc for IDE Recommendation
- added IntelliJ folder to ignore
updated php doc bloc @author so not to contain :
updated class documentation
updated class documentations. fixed issue in detecting of the gifsicle transcoder engine would be available or not.
added in dither order
added additional options to gifsicle
updated animated gif transcoders so that the save functions reflect the abstract parent save function
typeo
fixed small issue of whitespace
updated version in source
applied default Media::OVERWRITE_XXX functionality to animated gifs
Date: 1 year ago
Size: 10,463 bytes
 

Contents

Class file image Download
<?php /** * This file is part of the PHP Video Toolkit v2 package. * * @author Oliver Lillie (aka buggedcom) <publicmail@buggedcom.co.uk> * @license Dual licensed under MIT and GPLv2 * @copyright Copyright (c) 2008-2014 Oliver Lillie <http://www.buggedcom.co.uk> * @package PHPVideoToolkit V2 * @version 2.1.7-beta * @uses ffmpeg http://ffmpeg.sourceforge.net/ */ namespace PHPVideoToolkit; /** * This class provides an animated gif transcoder engine that uses gifsicle and either imagemagic convert or PHP gd to create * animated gifs. This engine is the prefered engine in conjunction with convert. GD still does ok, but takes much much longer. * * @author Oliver Lillie */ class AnimatedGifTranscoderGifsicle extends AnimatedGifTranscoderAbstract { /** * A list of temporary gif files to clean up. * @var array */ protected $_tidy_up_gifs; /** * Constructor * * @access public * @author Oliver Lillie * @param Config $config The PHPVideoToolit\Config object. */ public function __construct(Config $config=null) { parent::__construct($config); $this->_tidy_up_gifs = array(); } /** * Destructor. Automatically removes temporary gif files. * * @access public * @author Oliver Lillie */ public function __destruct() { // tidy up any converted image to gifs. if(empty($this->_tidy_up_gifs) === false) { foreach ($this->_tidy_up_gifs as $path) { @unlink($path); } $this->_tidy_up_gifs = array(); } } /** * Adds a frame to the gif. This overrides the parent abstract class addFrame function. * * @access public * @author Oliver Lillie * @param Image $image The image source that you wish to add as a frame to the gif. * @return AnimatedGifTranscoderGifsicle Returns the current object. */ public function addFrame(Image $image) { // gifsicle doesn't work with non-gif images so we must convert a frame to a gif // if it is not a gif. $gif_path = $this->_convertFrameToGif($image->getMediaPath()); array_push($this->_frames, $gif_path); return $this; } /** * Converts a given image if the image is not a gif, to a gif, using either imagemagic convert or PHP GD. * Convert is preferred as it is quicker. * * @access public * @author Oliver Lillie * @param string $frame_path The file paht of the image to convert. * @return string Returns the new file path if the image was converted, otherwise returns the old file path. * @throws AnimatedGifException If imagemagick convert is user but encounters an error. * @throws \RuntimeException If PHP GD is used and imagegif is not available on the current system. * @throws AnimatedGifException If the image given to convert is not supported by PHP GD. * @throws AnimatedGifException If the image fails to convert to a gif using PHP GD. * @throws AnimatedGifException If the image fails to convert. * @throws AnimatedGifException If the image fails to convert but a path was generated. * @throws AnimatedGifException If the image fails to convert but a file was generated by 0 bytes in size. */ protected function _convertFrameToGif($frame_path) { $data = getimagesize($frame_path); if($data['mime'] === 'image/gif') { return $frame_path; } $gif_path = null; // first try with imagemagick convert as imagemaigk produces better gifs if($this->_config->convert) { $process = new ProcessBuilder('convert', $this->_config); $process->add($frame_path) ->add($frame_path.'.convert-convert.gif'); if($this->_config->gif_transcoder_convert_use_dither === true) { $process->add('-ordered-dither')->add($this->_config->gif_transcoder_convert_dither_order); } if($this->_config->gif_transcoder_convert_use_map === true) { $process->add('+map'); } $exec = $process->getExecBuffer(); $exec->setBlocking(true) ->execute(); if($exec->hasError() === true) { throw new AnimatedGifException('When attempting to convert "'.$frame_path.'" to a gif, convert encountered an error. Convert reported: '.$exec->getLastLine()); } $gif_path = $frame_path.'.convert-convert.gif'; } // if we still have no gif path then try with php gd. if(empty($gif_path) === true) { if(function_exists('imagegif') === false) { throw new \RuntimeException('PHP GD\'s function `imagegif` is not available, as a result the frame could not be added.'); } $im = false; $data = getimagesize($frame_path); switch($data['mime']) { case 'image/jpeg' : $im = @imagecreatefromjpeg($frame_path); break; case 'image/png' : $im = @imagecreatefrompng($frame_path); break; case 'image/xbm' : $im = @imagecreatefromwbmp($frame_path); break; case 'image/xpm' : $im = @imagecreatefromxpm($frame_path); break; } if($im === false) { throw new AnimatedGifException('Unsupported image type.'); } // save as a gif $gif_path = $frame_path.'.convert-php.gif'; if(imagegif($im, $gif_path) === false) { throw new AnimatedGifException('Unable to convert frame to gif using PHP GD.'); } imagedestroy($im); } if(empty($gif_path) === true) { throw new AnimatedGifException('Unable to convert frame to gif.'); } else if(is_file($gif_path) === false) { throw new AnimatedGifException('Unable to convert frame to gif, however the gif conversion path was set.'); } else if(filesize($gif_path) === 0) { throw new AnimatedGifException('Unable to convert frame to gif, as a gif was produced, however it was a zero byte file.'); } array_push($this->_tidy_up_gifs, $gif_path); return $gif_path; } /** * Saves the animated gif. * * @access public * @author Oliver Lillie * @param string $save_path The path to save the animated gif to. * @return Image Returns a new instance of PHPVideoToolkit\Image with the new animated gif as the src. * @throws AnimatedGifException If the convert process encounters an error. */ public function save($save_path) { $save_path = parent::save($save_path); // build the gifsicle process $gifsicle_process = new ProcessBuilder('gifsicle', $this->_config); // add in all the frames foreach ($this->_frames as $path) { $gifsicle_process->add($path); } // set the looping count if($this->_loop_count === AnimatedGif::UNLIMITED_LOOPS) { $gifsicle_process->add('-l'); } else { $gifsicle_process->add('-l')->add($this->_loop_count); } // set the frame duration //$gifsicle_process->add('-d')->add($frame_delay*1000); // add the output path $gifsicle_process->add('-o')->add($save_path); // execute the process. $exec = $gifsicle_process->getExecBuffer(); $exec->setBlocking(true) ->execute(); $this->__destruct(); // check for any gifsicle errors if($exec->hasError() === true) { throw new AnimatedGifException('AnimatedGif save using `gifsicle` save "'.$save_path.'" failed. Any additional gifsicle message follows: '.$exec->getBuffer()); } return new Image($save_path, $this->_config); } /** * Determines if the gifsicle/convert or gifsicle/php transcoder engine is available on the current system. * * @access public * @static * @author Oliver Lillie * @param Config $config The configuration object. * @return boolean Returns true if this engine can be used, otherwise false. */ public static function available(Config $config) { if($config->gifsicle === null) { return false; } try { Binary::locate($config->gifsicle); try { Binary::locate($config->convert); return true; } catch(Exception $e) { return function_exists('imagegif'); } } catch(Exception $e) { return false; } } }