1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 23:02:42 +01:00

Preserving the Animation of Gif Images

Summary: Preserving animation of GIF profile Pictures

Test Plan: Uploaded Animated images as profile pictures to check if the animation of gif images is preserved and it does :) somewhat !

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Differential Revision: https://secure.phabricator.com/D4833
This commit is contained in:
Afaque Hussain 2013-02-08 09:14:28 -08:00 committed by epriestley
parent cc084822da
commit 9c19e9b7d8
6 changed files with 103 additions and 9 deletions

View file

@ -882,6 +882,10 @@ return array(
'image/vnd.microsoft.icon' => true, 'image/vnd.microsoft.icon' => true,
), ),
// Configuration option for enabling imagemagick
// to resize animated profile pictures (gif)
'files.enable-imagemagick' => false,
// -- Storage --------------------------------------------------------------- // // -- Storage --------------------------------------------------------------- //
// Phabricator allows users to upload files, and can keep them in various // Phabricator allows users to upload files, and can keep them in various

View file

@ -1261,6 +1261,7 @@ phutil_register_library_map(array(
'PhabricatorSetupCheckExtraConfig' => 'applications/config/check/PhabricatorSetupCheckExtraConfig.php', 'PhabricatorSetupCheckExtraConfig' => 'applications/config/check/PhabricatorSetupCheckExtraConfig.php',
'PhabricatorSetupCheckFacebook' => 'applications/config/check/PhabricatorSetupCheckFacebook.php', 'PhabricatorSetupCheckFacebook' => 'applications/config/check/PhabricatorSetupCheckFacebook.php',
'PhabricatorSetupCheckGD' => 'applications/config/check/PhabricatorSetupCheckGD.php', 'PhabricatorSetupCheckGD' => 'applications/config/check/PhabricatorSetupCheckGD.php',
'PhabricatorSetupCheckImagemagick' => 'applications/config/check/PhabricatorSetupCheckImagemagick.php',
'PhabricatorSetupCheckInvalidConfig' => 'applications/config/check/PhabricatorSetupCheckInvalidConfig.php', 'PhabricatorSetupCheckInvalidConfig' => 'applications/config/check/PhabricatorSetupCheckInvalidConfig.php',
'PhabricatorSetupCheckMail' => 'applications/config/check/PhabricatorSetupCheckMail.php', 'PhabricatorSetupCheckMail' => 'applications/config/check/PhabricatorSetupCheckMail.php',
'PhabricatorSetupCheckMySQL' => 'applications/config/check/PhabricatorSetupCheckMySQL.php', 'PhabricatorSetupCheckMySQL' => 'applications/config/check/PhabricatorSetupCheckMySQL.php',
@ -2677,6 +2678,7 @@ phutil_register_library_map(array(
'PhabricatorSetupCheckExtraConfig' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckExtraConfig' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckFacebook' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckFacebook' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckGD' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckGD' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckImagemagick' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckInvalidConfig' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckInvalidConfig' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckMail' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckMail' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckMySQL' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckMySQL' => 'PhabricatorSetupCheck',

View file

@ -0,0 +1,25 @@
<?php
final class PhabricatorSetupCheckImagemagick extends PhabricatorSetupCheck {
protected function executeChecks() {
$imagemagick = PhabricatorEnv::getEnvConfig('files.enable-imagemagick');
if ($imagemagick) {
list($err) = exec_manual('which convert');
if ($err) {
$message = pht(
'You have enabled Imagemagick in your config, but the \'convert\''.
' binary is not in the webserver\'s $PATH. Disable imagemagick'.
' or make it available to the webserver.');
$this->newIssue('files.enable-imagemagick')
->setName(pht(
"'convert' binary not found or Imagemagick is not installed."))
->setMessage($message)
->addPhabricatorConfig('files.enable-imagemagick')
->addPhabricatorConfig('environment.append-paths');
}
}
}
}

View file

@ -95,8 +95,14 @@ final class PhabricatorImageTransformer {
$scaled_y = $min_y; $scaled_y = $min_y;
} }
$cropped = $this->applyScaleWithImagemagick($file, $x, $scaled_y);
if ($cropped != null) {
return $cropped;
}
$img = $this->applyScaleTo( $img = $this->applyScaleTo(
$img, $file,
$x, $x,
$scaled_y); $scaled_y);
@ -131,11 +137,13 @@ final class PhabricatorImageTransformer {
* Very crudely scale an image up or down to an exact size. * Very crudely scale an image up or down to an exact size.
*/ */
private function crudelyScaleTo(PhabricatorFile $file, $dx, $dy) { private function crudelyScaleTo(PhabricatorFile $file, $dx, $dy) {
$data = $file->loadFileData(); $scaled = $this->applyScaleWithImagemagick($file, $dx, $dy);
$src = imagecreatefromstring($data);
$dst = $this->applyScaleTo($src, $dx, $dy); if ($scaled != null) {
return $scaled;
}
$dst = $this->applyScaleTo($file, $dx, $dy);
return $this->saveImageDataInAnyFormat($dst, $file->getMimeType()); return $this->saveImageDataInAnyFormat($dst, $file->getMimeType());
} }
@ -147,17 +155,22 @@ final class PhabricatorImageTransformer {
return $dst; return $dst;
} }
private function applyScaleTo($src, $dx, $dy) { private function applyScaleTo(PhabricatorFile $file, $dx, $dy) {
$data = $file->loadFileData();
$src = imagecreatefromstring($data);
$x = imagesx($src); $x = imagesx($src);
$y = imagesy($src); $y = imagesy($src);
$scale = min(($dx / $x), ($dy / $y), 1); $scale = min(($dx / $x), ($dy / $y), 1);
$dst = $this->getBlankDestinationFile($dx, $dy);
$sdx = $scale * $x; $sdx = $scale * $x;
$sdy = $scale * $y; $sdy = $scale * $y;
$dst = $this->getBlankDestinationFile($dx, $dy);
imagesavealpha($dst, true);
imagefill($dst, 0, 0, imagecolorallocatealpha($dst, 255, 255, 255, 127));
imagecopyresampled( imagecopyresampled(
$dst, $dst,
$src, $src,
@ -167,6 +180,7 @@ final class PhabricatorImageTransformer {
$x, $y); $x, $y);
return $dst; return $dst;
} }
public static function getPreviewDimensions(PhabricatorFile $file, $size) { public static function getPreviewDimensions(PhabricatorFile $file, $size) {
@ -337,7 +351,7 @@ final class PhabricatorImageTransformer {
private function saveImageDataInAnyFormat($data, $preferred_mime = '') { private function saveImageDataInAnyFormat($data, $preferred_mime = '') {
switch ($preferred_mime) { switch ($preferred_mime) {
case 'image/gif': // GIF doesn't support true color. case 'image/gif': // Gif doesn't support true color
case 'image/png': case 'image/png':
if (function_exists('imagepng')) { if (function_exists('imagepng')) {
ob_start(); ob_start();
@ -368,4 +382,43 @@ final class PhabricatorImageTransformer {
return $img; return $img;
} }
private function applyScaleWithImagemagick(PhabricatorFile $file, $dx, $dy) {
$img_type = $file->getMimeType();
$imagemagick = PhabricatorEnv::getEnvConfig('files.enable-imagemagick');
if ($img_type != 'image/gif' || $imagemagick == false) {
return null;
}
$data = $file->loadFileData();
$src = imagecreatefromstring($data);
$x = imagesx($src);
$y = imagesy($src);
$scale = min(($dx / $x), ($dy / $y), 1);
$sdx = $scale * $x;
$sdy = $scale * $y;
$input = new TempFile();
Filesystem::writeFile($input, $data);
$resized = new TempFile();
list($err) = exec_manual(
'convert %s -coalesce -resize %sX%s\! %s'
, $input, $sdx, $sdy, $resized
);
if (!$err) {
$new_data = Filesystem::readFile($resized);
return $new_data;
} else {
return null;
}
}
} }

View file

@ -119,6 +119,16 @@ final class PhabricatorFilesConfigOptions
"value and the UI will then reflect the actual configured ". "value and the UI will then reflect the actual configured ".
"limit.")) "limit."))
->addExample('10M', pht("Valid setting.")), ->addExample('10M', pht("Valid setting.")),
$this->newOption('files.enable-imagemagick', 'bool', false)
->setBoolOptions(
array(
pht('Enable'),
pht('Disable')
))->setDescription(
pht("This option will enable animated gif images".
"to be set as profile pictures. The \'convert\' binary ".
"should be available to the webserver for this to work")),
); );
} }