diff --git a/src/applications/files/PhabricatorImageTransformer.php b/src/applications/files/PhabricatorImageTransformer.php index 3273f84c50..fcb92a79a8 100644 --- a/src/applications/files/PhabricatorImageTransformer.php +++ b/src/applications/files/PhabricatorImageTransformer.php @@ -6,7 +6,7 @@ final class PhabricatorImageTransformer { PhabricatorFile $file, $upper_text, $lower_text) { - $image = $this->applyMemeTo($file, $upper_text, $lower_text); + $image = $this->applyMemeToFile($file, $upper_text, $lower_text); return PhabricatorFile::newFromFileData( $image, array( @@ -257,11 +257,43 @@ final class PhabricatorImageTransformer { return self::saveImageDataInAnyFormat($dst, $file->getMimeType()); } - private function applyMemeTo( + private function applyMemeToFile( PhabricatorFile $file, $upper_text, $lower_text) { $data = $file->loadFileData(); + + $img_type = $file->getMimeType(); + $imagemagick = PhabricatorEnv::getEnvConfig('files.enable-imagemagick'); + + if ($img_type != 'image/gif' || $imagemagick == false) { + return $this->applyMemeTo( + $data, $upper_text, $lower_text, $img_type); + } + + $data = $file->loadFileData(); + $input = new TempFile(); + Filesystem::writeFile($input, $data); + + list($out) = execx('convert %s info:', $input); + $split = phutil_split_lines($out); + if (count($split) > 1) { + return $this->applyMemeWithImagemagick( + $input, + $upper_text, + $lower_text, + count($split), + $img_type); + } else { + return $this->applyMemeTo($data, $upper_text, $lower_text, $img_type); + } + } + + private function applyMemeTo( + $data, + $upper_text, + $lower_text, + $mime_type) { $img = imagecreatefromstring($data); $phabricator_root = dirname(phutil_get_library_root('phabricator')); $font_root = $phabricator_root.'/resources/font/'; @@ -314,7 +346,7 @@ final class PhabricatorImageTransformer { break; } } - return self::saveImageDataInAnyFormat($img, $file->getMimeType()); + return self::saveImageDataInAnyFormat($img, $mime_type); } private function makeImageWithTextBorder($img, $font_size, $x, $y, @@ -355,6 +387,10 @@ final class PhabricatorImageTransformer { public static function saveImageDataInAnyFormat($data, $preferred_mime = '') { switch ($preferred_mime) { case 'image/gif': // Gif doesn't support true color + ob_start(); + imagegif($data); + return ob_get_clean(); + break; case 'image/png': if (function_exists('imagepng')) { ob_start(); @@ -423,4 +459,35 @@ final class PhabricatorImageTransformer { } + private function applyMemeWithImagemagick( + $input, + $above, + $below, + $count, + $img_type) { + + $output = new TempFile(); + + execx('convert %s -coalesce +adjoin %s_%%09d', + $input, + $input); + + for ($ii = 0; $ii < $count; $ii++) { + $frame_name = sprintf('%s_%09d', $input, $ii); + $output_name = sprintf('%s_%09d', $output, $ii); + + $frame_data = Filesystem::readFile($frame_name); + $memed_frame_data = $this->applyMemeTo( + $frame_data, + $above, + $below, + $img_type); + Filesystem::writeFile($output_name, $memed_frame_data); + } + + execx('convert -loop 0 %s_* %s', $output, $output); + + return Filesystem::readFile($output); + } + }