Please upgrade here. These earlier versions are no longer being updated and have security issues.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.
Options

Animated Avatars

merfedmerfed New
edited July 2011 in Vanilla 2.0 - 2.8
Anyway to make the image uploader accept gifs?
Tagged:

Answers

  • Options
    Merfed,
    When you upload an Avatar, three files are generated. Full size, mini & thumb views. These are made using the standard GD package and unfortunately will only copy the first frame of an animated gif. You have two different ways to solve your problem.
    1. Manually resize the gifs & overwrite your original avatars (quick but just for you).
    2. Rewrite the routines that upload & resize the avatars to utilise ImageMagick (lot of work but all users will benefit).
    Hope this helps.
  • Options
    Merfed,
    Just an update. A variation to choice 2 is to test for animated gifs and copy without resizing if so. Found this code which tests such on http://www.php.net/manual/en/function.imagecreatefromgif.php#88005
    <?php function is_ani($filename) { if(!($fh = @fopen($filename, 'rb'))) return false; $count = 0; //an animated gif contains multiple "frames", with each frame having a //header made up of: // * a static 4-byte sequence (\x00\x21\xF9\x04) // * 4 variable bytes // * a static 2-byte sequence (\x00\x2C) (some variants may use \x00\x21 ?) // We read through the file til we reach the end of the file, or we've found // at least 2 frame headers while(!feof($fh) && $count < 2) { $chunk = fread($fh, 1024 * 100); //read 100kb at a time $count += preg_match_all('#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s', $chunk, $matches); } fclose($fh); return $count > 1; } ?>
  • Options
    Hi there @gnome2 & @merfed! Add animated gifs in the avatar it would be awesome!

    Where in the code did I have to test if it is an animated gif? Could you guys help me? =)

    Thanks in advance!
  • Options
    Psycocandy - I had another look and it gets a bit more involved as the download is re-scaled to three different sizes (thumb, preview & profile) and it is this re-scaling that wipes out the animation. If the scaling was performed via css (possibly/idealy within your theme) as opposed to fixed sizing then an animated gif between 43 - 50 pixels square could be uploaded and work.

    Hey after a lot of parking logging statements in code I have finally solved the animated avatar problem! Three files plus maybe your style.css need be changed.
    Vanilla Animated Gifs

    File: vanilla/applications/dashboard/controllers/class.profilecontroller.php function picture() change: $UploadImage = new Gdn_UploadImage(); try { // Validate the upload $TmpImage = $UploadImage->ValidateUpload('Picture'); // Generate the target image name. $TargetImage = $UploadImage->GenerateTargetName(PATH_LOCAL_UPLOADS); $ImageBaseName = pathinfo($TargetImage, PATHINFO_BASENAME); to: $UploadImage = new Gdn_UploadImage(); try { // Validate the upload $TmpImage = $UploadImage->ValidateUpload('Picture'); list($Width, $Height, $Type, $Attributes) = getimagesize($TmpImage); $OutputTypes = array(1 => 'gif', 2 => 'jpeg', 3 => 'png'); $FileType = $OutputTypes[$Type]; // Generate the target image name. $TargetImage = $UploadImage->GenerateTargetName(PATH_LOCAL_UPLOADS); $pos = strpos($TargetImage,'.'); if ($pos != 0) $TargetImage = substr($TargetImage,0,$pos); $TargetImage .= ".$FileType"; $ImageBaseName = pathinfo($TargetImage, PATHINFO_BASENAME); Reason: Even though $TmpImage is the same filetype as what you are uploading it carries the file extent of '.tmp' so we are forcing the $TargetImage to carry the same file type. File: vanilla/library/core/functions.general.php add a new function (in alphabetical order): public function is_ani($filename) { if (!($fh = @fopen($filename, 'rb'))) return false; $count = 0; while(!feof($fh) && $count < 2) { $chunk = fread($fh, 1024 * 100); $count += preg_match_all('#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s', $chunk, $matches); } fclose($fh); return $count > 1; } Reason: Function required to assertain if a GIF is animated or not. File: vanilla/library/core/class.uploadimage.php function SaveImageAs() change: $TargetPath = PATH_LOCAL_UPLOADS.'/'.ltrim($TargetParsed['Name'], '/'); if (!file_exists(dirname($TargetPath))) mkdir(dirname($TargetPath), 0777, TRUE); // Don't resize if the source dimensions are smaller than the target dimensions $XCoord = GetValue('SourceX', $Options, 0); to: $TargetPath = PATH_LOCAL_UPLOADS.'/'.ltrim($TargetParsed['Name'], '/'); $pos = strpos($TargetPath,'.'); if ($pos != 0) $TargetPath = substr($TargetPath,0,$pos); $TargetPath .= ".$OutputType"; if (!file_exists(dirname($TargetPath))) mkdir(dirname($TargetPath), 0777, TRUE); // if gif then check for animated - dont re-size or crop animated gif, just copy as is if ($OutputType == 1 && is_ani($Source)) copy($Source, $Target); else { // Don't resize if the source dimensions are smaller than the target dimensions $XCoord = GetValue('SourceX', $Options, 0); and change: if ($OutputType == 'gif') imagegif($TargetImage, $TargetPath); elseif ($OutputType == 'png') imagepng($TargetImage, $TargetPath, (int)($ImageQuality/10)); else imagejpeg($TargetImage, $TargetPath, $ImageQuality); // Allow a plugin to move the file to a differnt location. $Sender = new stdClass(); $Sender->EventArguments = array(); to: if ($OutputType == 'gif') imagegif($TargetImage, $TargetPath); elseif ($OutputType == 'png') imagepng($TargetImage, $TargetPath, (int)($ImageQuality/10)); else imagejpeg($TargetImage, $TargetPath, $ImageQuality); } // Allow a plugin to move the file to a differnt location. $Sender = new stdClass(); $Sender->EventArguments = array(); Reason: The first change tests for animated gifs and performs a straight copy without resizing and the second is the closing brace to complete it.

    These changes work on 2.0.18b
    Note: animated avatars don't get resized when uploading so don't have them bigger than 50x50 pixels. They will be resized by css on display.

    Now this isn't a cure-all. I'm sure the developers could do better (hint here).
  • Options
    Just an update: change the height/width statements within your style.css for the thumbs / images to be
    height: expression(this.height > 50 ? 50: true);
    width: expression(this.width > 50 ? 50: true);

    or whatever maximums you wish.
  • Options
    I would love to get animated avatars in the 2.0.17.10 version... Any chances of this? =)
  • Options
    LincLinc Detroit Admin
    Probably not, no. I'm sure this could be implemented with a plugin, but it's not a priority for core.
Sign In or Register to comment.