/** * Saves the animated gif. * * @access public * @author Oliver Lillie * @param string $save_path * @param float $frame_delay The delay of each frame. * @return Image */ public function save($save_path, $frame_delay = 0.1) { parent::save($save_path, $frame_delay); // build the gif creator process $gc = new \GifCreator\GifCreator(); // add in all the frames $durations = array(); $frame_duration = $frame_delay * 100; foreach ($this->_frames as $path) { array_push($durations, $frame_duration); } $gc->create($this->_frames, $durations, $this->_loop_count === AnimatedGif::UNLIMITED_LOOPS ? '0' : $this->_loop_count + 1); $gif_data = $gc->getGif(); // check for errors or put the data into the file. if (empty($gif_data) === true || file_put_contents($save_path, $gif_data) === false) { throw new FfmpegProcessPostProcessException('AnimatedGif save using `php` "' . $save_path . '" failed.'); } return new Image($save_path, $this->_config); }
/** * Saves the animated gif. * * @access public * @author Oliver Lillie * @param string $save_path The path to save the animated gif to. * @return PHPVideoToolkit\Image Returns a new instance of PHPVideoToolkit\Image with the new animated gif as the src. * @throws PHPVideoToolkit\AnimatedGifException If an empty gif is generated. * @throws PHPVideoToolkit\AnimatedGifException If the gif couldn't be saved to the filesystem. */ public function save($save_path) { $save_path = parent::save($save_path); // build the gif creator process require_once dirname(dirname(dirname(__FILE__))) . '/vendor/sybio/gif-creator/src/GifCreator/GifCreator.php'; $gc = new \GifCreator\GifCreator(); // add in all the frames $durations = array(); $frame_duration = $this->_frame_delay * 100; foreach ($this->_frames as $path) { array_push($durations, $frame_duration); } $gc->create($this->_frames, $durations, $this->_loop_count === AnimatedGif::UNLIMITED_LOOPS ? '0' : $this->_loop_count + 1); $gif_data = $gc->getGif(); // check for errors or put the data into the file. if (empty($gif_data) === true) { throw new AnimatedGifException('AnimatedGif using `php` generated an empty gif.'); } if (file_put_contents($save_path, $gif_data) === false) { throw new AnimatedGifException('AnimatedGif save to filesystem failed using "' . $save_path . '".'); } return new Image($save_path, $this->_config); }
/** * Create. * * This method creates the thumbnail from the video. * * @param string $videoFile Video file to process * @param string $thumbnailFile Output gif * @param int|null $count Number of frames to use * @param int|null $interval The interval beetween the frames of the gif * @param int|null $width Width of the gif * @param int|null $height Height of the gif * @param int|null $start The start of the video part * @param int|null $end The end of the video part * * @throws VideoException If error during procession or writing. */ public function create($videoFile, $thumbnailFile, $count = null, $interval = null, $width = null, $height = null, $start = null, $end = null) { $count = $count ?: $this->defaults['count']; $interval = $interval ?: $this->defaults['interval']; $width = $width ?: $this->defaults['width']; $height = $height ?: $this->defaults['height']; try { $ffmpeg = FFMpeg::create(); $ffprobe = FFProbe::create(); } catch (\Exception $e) { throw new VideoException('Cannot start FFMpeg or FFProbe', 0, $e); } try { // Determine the duration of the video $duration = $ffprobe->format($videoFile)->get('duration'); } catch (\Exception $e) { throw new VideoException(sprintf('Cannot determine the duration of %s', $videoFile), 0, $e); } // If invalid start or end time, assume it is the start and the end // of the video. $start = max(0, $start ?: 0); $end = min($duration, $end ?: $duration); $delay = (double) ($end - $start) / ($count + 1); $video = $ffmpeg->open($videoFile); $hashDir = $this->tmpDir . '/video-gif/' . md5($videoFile . time()); if (!file_exists($hashDir)) { mkdir($hashDir, 0777, true); } $pos = $start; $frames = array(); $durations = array(); // Grab frames for ($i = 0; $i < $count; ++$i) { $pos += $delay; $video->frame(TimeCode::fromSeconds($pos))->save(sprintf($hashDir . '/tmp-frame%03d.jpg', $i)); Image::open(sprintf($hashDir . '/tmp-frame%03d.jpg', $i))->cropResize($width, $height)->save(sprintf($hashDir . '/frame%03d.jpg', $i)); $frames[] = sprintf($hashDir . '/frame%03d.jpg', $i); $durations[] = $interval; } $gc = new GifCreator(); $gc->create($frames, $durations, 0); $this->removeDirectory($hashDir); if (false === @file_put_contents($thumbnailFile, $gc->getGif())) { throw new VideoException(sprintf('Cannot write %s', $thumbnailFile)); } }
public function automatic_reduction($file, $image_url) { $filetype = $this->getFileType($file); if ((!empty($this->maximum_picture_size['width']) || !empty($this->maximum_picture_size['height'])) && ($this->width > $this->maximum_picture_size['width'] || $this->height > $this->maximum_picture_size['height'])) { if ($this->width > $this->height) { $maximum_picture_size_width = empty($this->maximum_picture_size['width']) ? $this->width * $this->maximum_picture_size['height'] / $this->height : $this->maximum_picture_size['width']; $new_width = intval($maximum_picture_size_width); $new_height = intval($this->height * $maximum_picture_size_width / $this->width); } else { $maximum_picture_size_height = empty($this->maximum_picture_size['height']) ? $this->height * $this->maximum_picture_size['width'] / $this->width : $this->maximum_picture_size['height']; $new_width = intval($this->width * $maximum_picture_size_height / $this->height); $new_height = intval($maximum_picture_size_height); } $layer = ImageWorkshop::initFromString($file); if ($filetype == 'gif' && GifFrameExtractor\GifFrameExtractor::isAnimatedGif($this->temp)) { $gfe = new GifFrameExtractor\GifFrameExtractor(); $frames = $gfe->extract($this->temp, true); $retouchedFrames = array(); foreach ($frames as $frame) { $frameLayer = ImageWorkshop::initFromResourceVar($frame['image']); $frameLayer->resizeInPixel($new_width, $new_height); $retouchedFrames[] = $frameLayer->getResult(); } $gc = new GifCreator\GifCreator(); $gc->create($retouchedFrames, $gfe->getFrameDurations(), 0); $file = $gc->getGif(); } else { $layer->resizeInPixel($new_width, $new_height, true); ob_start(); switch ($filetype) { case 'jpg': case 'jpeg': ImageJpeg($layer->getResult(), null, 75); break; case 'png': imagealphablending($layer->getResult(), false); imagesavealpha($layer->getResult(), true); ImagePng($layer->getResult()); break; case 'gif': ImageGif($layer->getResult(), null, 75); break; } $file = ob_get_contents(); ob_end_clean(); } imagedestroy($layer->getResult()); $this->width = $new_width; $this->height = $new_height; } return $file; }
/** * Generates the gif file. * @throws \Exception */ private function render_gif() { $diff = $this->end_time - $this->start_time; $now = $this->start_time; for ($diff; $diff >= 0; $diff -= $this->step) { $dtF = new DateTime("@{$now}"); $dtT = new DateTime("@{$this->end_time}"); $text = $dtF->diff($dtT)->format('%a D / %h H / %i M / %s S'); $last_frame = false; if ($diff == 0) { $last_frame = true; } $this->frames[] = $this->render_frame($text, $last_frame); if ($diff == 0) { $this->durations[] = -1; } else { $this->durations[] = 100 * $this->step; } $now += $this->step; } $gc = new GifCreator(); $gc->create($this->frames, $this->durations, 0); $this->gif = $gc->getGif(); }