mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-25 16:22:43 +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:
parent
cc084822da
commit
9c19e9b7d8
6 changed files with 103 additions and 9 deletions
|
@ -882,6 +882,10 @@ return array(
|
|||
'image/vnd.microsoft.icon' => true,
|
||||
),
|
||||
|
||||
// Configuration option for enabling imagemagick
|
||||
// to resize animated profile pictures (gif)
|
||||
'files.enable-imagemagick' => false,
|
||||
|
||||
// -- Storage --------------------------------------------------------------- //
|
||||
|
||||
// Phabricator allows users to upload files, and can keep them in various
|
||||
|
|
|
@ -1261,6 +1261,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSetupCheckExtraConfig' => 'applications/config/check/PhabricatorSetupCheckExtraConfig.php',
|
||||
'PhabricatorSetupCheckFacebook' => 'applications/config/check/PhabricatorSetupCheckFacebook.php',
|
||||
'PhabricatorSetupCheckGD' => 'applications/config/check/PhabricatorSetupCheckGD.php',
|
||||
'PhabricatorSetupCheckImagemagick' => 'applications/config/check/PhabricatorSetupCheckImagemagick.php',
|
||||
'PhabricatorSetupCheckInvalidConfig' => 'applications/config/check/PhabricatorSetupCheckInvalidConfig.php',
|
||||
'PhabricatorSetupCheckMail' => 'applications/config/check/PhabricatorSetupCheckMail.php',
|
||||
'PhabricatorSetupCheckMySQL' => 'applications/config/check/PhabricatorSetupCheckMySQL.php',
|
||||
|
@ -2677,6 +2678,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSetupCheckExtraConfig' => 'PhabricatorSetupCheck',
|
||||
'PhabricatorSetupCheckFacebook' => 'PhabricatorSetupCheck',
|
||||
'PhabricatorSetupCheckGD' => 'PhabricatorSetupCheck',
|
||||
'PhabricatorSetupCheckImagemagick' => 'PhabricatorSetupCheck',
|
||||
'PhabricatorSetupCheckInvalidConfig' => 'PhabricatorSetupCheck',
|
||||
'PhabricatorSetupCheckMail' => 'PhabricatorSetupCheck',
|
||||
'PhabricatorSetupCheckMySQL' => 'PhabricatorSetupCheck',
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -95,8 +95,14 @@ final class PhabricatorImageTransformer {
|
|||
$scaled_y = $min_y;
|
||||
}
|
||||
|
||||
$cropped = $this->applyScaleWithImagemagick($file, $x, $scaled_y);
|
||||
|
||||
if ($cropped != null) {
|
||||
return $cropped;
|
||||
}
|
||||
|
||||
$img = $this->applyScaleTo(
|
||||
$img,
|
||||
$file,
|
||||
$x,
|
||||
$scaled_y);
|
||||
|
||||
|
@ -131,11 +137,13 @@ final class PhabricatorImageTransformer {
|
|||
* Very crudely scale an image up or down to an exact size.
|
||||
*/
|
||||
private function crudelyScaleTo(PhabricatorFile $file, $dx, $dy) {
|
||||
$data = $file->loadFileData();
|
||||
$src = imagecreatefromstring($data);
|
||||
$scaled = $this->applyScaleWithImagemagick($file, $dx, $dy);
|
||||
|
||||
$dst = $this->applyScaleTo($src, $dx, $dy);
|
||||
if ($scaled != null) {
|
||||
return $scaled;
|
||||
}
|
||||
|
||||
$dst = $this->applyScaleTo($file, $dx, $dy);
|
||||
return $this->saveImageDataInAnyFormat($dst, $file->getMimeType());
|
||||
}
|
||||
|
||||
|
@ -147,17 +155,22 @@ final class PhabricatorImageTransformer {
|
|||
return $dst;
|
||||
}
|
||||
|
||||
private function applyScaleTo($src, $dx, $dy) {
|
||||
private function applyScaleTo(PhabricatorFile $file, $dx, $dy) {
|
||||
$data = $file->loadFileData();
|
||||
$src = imagecreatefromstring($data);
|
||||
|
||||
$x = imagesx($src);
|
||||
$y = imagesy($src);
|
||||
|
||||
$scale = min(($dx / $x), ($dy / $y), 1);
|
||||
|
||||
$dst = $this->getBlankDestinationFile($dx, $dy);
|
||||
|
||||
$sdx = $scale * $x;
|
||||
$sdy = $scale * $y;
|
||||
|
||||
$dst = $this->getBlankDestinationFile($dx, $dy);
|
||||
imagesavealpha($dst, true);
|
||||
imagefill($dst, 0, 0, imagecolorallocatealpha($dst, 255, 255, 255, 127));
|
||||
|
||||
imagecopyresampled(
|
||||
$dst,
|
||||
$src,
|
||||
|
@ -167,6 +180,7 @@ final class PhabricatorImageTransformer {
|
|||
$x, $y);
|
||||
|
||||
return $dst;
|
||||
|
||||
}
|
||||
|
||||
public static function getPreviewDimensions(PhabricatorFile $file, $size) {
|
||||
|
@ -337,7 +351,7 @@ final class PhabricatorImageTransformer {
|
|||
|
||||
private function saveImageDataInAnyFormat($data, $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':
|
||||
if (function_exists('imagepng')) {
|
||||
ob_start();
|
||||
|
@ -368,4 +382,43 @@ final class PhabricatorImageTransformer {
|
|||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -119,6 +119,16 @@ final class PhabricatorFilesConfigOptions
|
|||
"value and the UI will then reflect the actual configured ".
|
||||
"limit."))
|
||||
->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")),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue