/** * Resize Animated Gif Image according to given config and save it * @param string $fullpath * @param string $target * @param array $size * @return void */ public function resizeAnimatedImage($fullpath, $target, $size) { // Extract image using \GifFrameExtractor\GifFrameExtractor; //$gifExtractor = new \Intervention\Gif\Decoder($fullpath); //$decoded = $gifExtractor->decode(); $gifFrameExtractor = new \GifFrameExtractor\GifFrameExtractor(); $frames = $gifFrameExtractor->extract($fullpath); // Check if height or width is set to auto then resize must be according to the aspect ratio if ($size[0] == null || $size[1] == null) { // Resize each frames foreach ($frames as $frame) { $img = $this->interImage->make($frame['image']); $img->resize($size[0], $size[1], function ($constraint) { $constraint->aspectRatio(); }); // $img->save(str_replace('.', uniqid().'.', $target)); $framesProcessed[] = $img->getCore(); } } elseif ($size[2] == 'stretch') { // Stretch Image // Resize each frames foreach ($frames as $frame) { $img = $this->interImage->make($frame['image']); $img->resize($size[0], $size[1]); $framesProcessed[] = $img->getCore(); } } else { // Default Fit // Resize each frames foreach ($frames as $frame) { $img = $this->interImage->make($frame['image']); $img->fit($size[0], $size[1]); $framesProcessed[] = $img->getCore(); } } $gifCreator = new \GifCreator\GifCreator(); $gifCreator->create($framesProcessed, $gifFrameExtractor->getFrameDurations(), 0); $gifBinary = $gifCreator->getGif(); $gifCreator->reset(); \File::put($target, $gifBinary); // Release Memory unset($gifFrameExtractor); unset($gifCreator); }
/** * Process image types here and returns filename to write * * @param array $aFile uploaded file information * @param string $folder the file path * @param string $aName the file name * @param array $imageInfo image information array: width, height, resize_mode * * @return bool|string * @throws ImageWorkshopException * @throws Exception */ public function processImage($aFile, $folder, $aName, $imageInfo) { $ext = self::_getImageExt($aFile['type']); if (empty($ext)) { $this->setMessage(iaLanguage::getf('file_type_error', array('extension' => implode(', ', array_unique(self::$_typesMap))))); return false; } try { $path = IA_UPLOADS . $folder; $image = ImageWorkshop::initFromPath($aFile['tmp_name']); // save source image $image->save($path, self::SOURCE_PREFIX . $aName . $ext); // process thumbnails for files uploaded in CKEditor and other tools if (empty($imageInfo)) { // apply watermark $image = self::_applyWaterMark($image); $image->save($path, self::_createFilename($aName, $ext)); return true; } // check this is an animated GIF if (self::ALLOW_ANIMATED_GIFS && 'image/gif' == $aFile['type']) { require_once IA_INCLUDES . 'phpimageworkshop' . IA_DS . 'Core' . IA_DS . 'GifFrameExtractor.php'; $gifPath = $aFile['tmp_name']; if (GifFrameExtractor\GifFrameExtractor::isAnimatedGif($gifPath)) { // Extractions of the GIF frames and their durations $gfe = new GifFrameExtractor\GifFrameExtractor(); $frames = $gfe->extract($gifPath); // For each frame, we add a watermark and we resize it $retouchedFrames = array(); $thumbFrames = array(); foreach ($frames as $frame) { $frameLayer = ImageWorkshop::initFromResourceVar($frame['image']); $thumbLayer = ImageWorkshop::initFromResourceVar($frame['image']); $frameLayer->resizeInPixel($imageInfo['image_width'], $imageInfo['image_height'], true); $frameLayer = self::_applyWaterMark($frameLayer); $retouchedFrames[] = $frameLayer->getResult(); $thumbLayer->resizeInPixel($imageInfo['thumb_width'], $imageInfo['thumb_height'], true); $thumbFrames[] = $thumbLayer->getResult(); } // Then we re-generate the GIF require_once IA_INCLUDES . 'phpimageworkshop' . IA_DS . 'Core' . IA_DS . 'GifCreator.php'; $gc = new GifCreator\GifCreator(); $gc->create($retouchedFrames, $gfe->getFrameDurations(), 0); file_put_contents($path . self::_createFilename($aName, $ext), $gc->getGif()); $thumbCreator = new GifCreator\GifCreator(); $thumbCreator->create($thumbFrames, $gfe->getFrameDurations(), 0); file_put_contents($path . self::_createFilename($aName, $ext, true), $thumbCreator->getGif()); return self::_createFilename($folder . $aName, $ext, true); } } // save full image $largestSide = $imageInfo['image_width'] > $imageInfo['image_height'] ? $imageInfo['image_width'] : $imageInfo['image_height']; if ($largestSide) { $image->resizeByLargestSideInPixel($largestSide, true); } $image = self::_applyWaterMark($image); $image->save($path, self::_createFilename($aName, $ext)); // generate thumbnail $thumbWidth = $imageInfo['thumb_width'] ? $imageInfo['thumb_width'] : $this->iaCore->get('thumb_w'); $thumbHeight = $imageInfo['thumb_height'] ? $imageInfo['thumb_height'] : $this->iaCore->get('thumb_h'); if ($thumbWidth || $thumbHeight) { $thumb = ImageWorkshop::initFromPath($aFile['tmp_name']); switch ($imageInfo['resize_mode']) { case self::FIT: $thumb->resizeInPixel($thumbWidth, $thumbHeight, true, 0, 0, 'MM'); break; case self::CROP: $largestSide = $thumbWidth > $thumbHeight ? $thumbWidth : $thumbHeight; $thumb->cropMaximumInPixel(0, 0, 'MM'); $thumb->resizeInPixel($largestSide, $largestSide); $thumb->cropInPixel($thumbWidth, $thumbHeight, 0, 0, 'MM'); } $thumb->save($path, self::_createFilename($aName, $ext, true)); } } catch (Exception $e) { $this->iaView->setMessages(iaLanguage::get('invalid_image_file')); return false; } return self::_createFilename($folder . $aName, $ext, true); }
private function _resize_animated($usefile, $PHPThumb_method) { $_hash = md5(microtime(TRUE) . uniqid()) . uniqid(); $_frames = array(); $_cachefiles = array(); $_durations = array(); $_gfe = new GifFrameExtractor\GifFrameExtractor(); $_gc = new GifCreator\GifCreator(); // -------------------------------------------------------------------------- // Extract all the frames, resize them and save to the cache $_gfe->extract($usefile); $_i = 0; foreach ($_gfe->getFrames() as $frame) { // Define the filename $_filename = $_hash . '-' . $_i . '.gif'; $_temp_filename = $_hash . '-' . $_i . '-original.gif'; $_i++; // Set these for recompiling $_frames[] = $this->_cachedir . $_filename; $_cachefiles[] = $this->_cachedir . $_temp_filename; $_durations[] = $frame['duration']; // -------------------------------------------------------------------------- // Set some PHPThumb options $_options = array(); $_options['resizeUp'] = TRUE; // -------------------------------------------------------------------------- // Perform the resize; first save the original frame to disk imagegif($frame['image'], $this->_cachedir . $_temp_filename); $PHPThumb = new PHPThumb\GD($this->_cachedir . $_temp_filename, $_options); $PHPThumb->{$PHPThumb_method}($this->_width, $this->_height); // -------------------------------------------------------------------------- // Save cache version $PHPThumb->save($this->_cachedir . $_filename, strtoupper(substr($this->_extension, 1))); } // Recompile the resized images back into an animated gif and save to the cache // TODO: We assume the gif loops infinitely but we should really check. // Issue made on the libraries gitHub asking for this feature. // View here: https://github.com/Sybio/GifFrameExtractor/issues/3 $_gc->create($_frames, $_durations, 0); $_data = $_gc->getGif(); // -------------------------------------------------------------------------- // Output to browser header('Content-Type: image/gif', TRUE); echo $_data; // -------------------------------------------------------------------------- // Save to cache $this->load->helper('file'); write_file($this->_cachedir . $this->_cache_file, $_data); // -------------------------------------------------------------------------- // Remove cache frames foreach ($_frames as $frame) { @unlink($frame); } foreach ($_cachefiles as $frame) { @unlink($frame); } // -------------------------------------------------------------------------- // Kill script, th, th, that's all folks. // Stop the output class from hijacking our headers and // setting an incorrect Content-Type exit(0); }