From a4d16d5b3075d4c0d6bbbc7dca105115ef364f5d Mon Sep 17 00:00:00 2001 From: lunakid Date: Thu, 24 Apr 2014 12:18:16 +0200 Subject: [PATCH 001/120] Refer to Sybio's original stuff. --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 847eb0d..f9cabb3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +NOTE: This is just a working copy (fork) of https://github.com/Sybio/GifCreator, +for some wording fixes (of mistakes inherited from the original [GIFEncoder](https://gist.github.com/allometry/1438842) from Laszlo Zsidi), minor code cosmetics, and customizations. All the rest below +is just the verbatim copy of Clément Guillemain's original README, unchanged (yet). + # ================================ # GifCreator # ================================ @@ -64,4 +68,4 @@ this class: https://github.com/Sybio/ImageWorkshop ### About -The class reuses some part of code of "GIFEncoder.class.php" by László Zsidi (thanks to him). \ No newline at end of file +The class reuses some part of code of "GIFEncoder.class.php" by László Zsidi (thanks to him). From 2295761eeb290b516314db495d85a7686d67e636 Mon Sep 17 00:00:00 2001 From: lunakid Date: Thu, 24 Apr 2014 13:03:52 +0200 Subject: [PATCH 002/120] Code cosmetics (untested yet for regressions!) + Made $this->version a define (VERSION). + Made $this->errors really static (self::$errors). + Moved encodeAsciiToChar() out from the class to the namespace root as a general utility fn. + Moved getGif to the "public" section (and removed the Getter/Setter section). + Moved reset() closer up to the ctor. + Changed comments here & there. + Changed the error messages slightly (those might get removed anyway, though). + Whitespaces: fixed some tab/space mismatch etc. --- src/GifCreator/GifCreator.php | 379 +++++++++++++++++----------------- 1 file changed, 186 insertions(+), 193 deletions(-) diff --git a/src/GifCreator/GifCreator.php b/src/GifCreator/GifCreator.php index 0726243..47d2547 100644 --- a/src/GifCreator/GifCreator.php +++ b/src/GifCreator/GifCreator.php @@ -1,190 +1,208 @@ version a define (VERSION). ++ Made $this->errors really static (self::$errors). ++ Moved encodeAsciiToChar() out from the class to the namespace root as a general utility fn. ++ Moved getGif to the "public" section (and removed the Getter/Setter section). ++ Moved reset() closer up to the ctor. ++ Changed comments here & there. ++ Whitespaces: fixed some tab/space mismatch etc. +*/ /** * Create an animated GIF from multiple images * - * @version 1.0 - * @link https://github.com/Sybio/GifCreator - * @author Sybio (Clément Guillemain / @Sybio01) + * @link https://github.com/lunakid/GifCreator + * @author Sybio (Clément Guillemain / @Sybio01), lunakid (@GitHub, @Gmail, @SO etc.) * @license http://opensource.org/licenses/gpl-license.php GNU Public License - * @copyright Clément Guillemain + * @copyright Clément Guillemain, Szabolcs Szász */ + +namespace GifCreator; + class GifCreator { - /** - * @var string The gif string source (old: this->GIF) - */ - private $gif; - - /** - * @var string Encoder version (old: this->VER) - */ - private $version; - - /** - * @var boolean Check the image is build or not (old: this->IMG) - */ - private $imgBuilt; - - /** - * @var array Frames string sources (old: this->BUF) - */ + /** + * @var string The generated (binary) image + */ + private $gif; + + /** + * @var boolean Has the image been built or not + */ + private $imgBuilt; + + /** + * @var array Frames string sources + */ private $frameSources; - - /** - * @var integer Gif loop (old: this->LOP) - */ + + /** + * @var integer Gif loop + */ private $loop; - - /** - * @var integer Gif dis (old: this->DIS) - */ + + /** + * @var integer Gif dis [!!?] + */ private $dis; - - /** - * @var integer Gif color (old: this->COL) - */ + + /** + * @var integer Gif color + */ private $colour; - - /** - * @var array (old: this->ERR) - */ - private $errors; + + /** + * @var array + */ + private static $errors; - // Methods - // =================================================================================== + // Methods + // =================================================================================== - /** - * Constructor - */ - public function __construct() - { - $this->reset(); - - // Static data - $this->version = 'GifCreator: Under development'; - $this->errors = array( - 'ERR00' => 'Does not supported function for only one image.', - 'ERR01' => 'Source is not a GIF image.', - 'ERR02' => 'You have to give resource image variables, image URL or image binary sources in $frames array.', - 'ERR03' => 'Does not make animation from animated GIF source.', - ); - } + public function __construct() + { + $this->reset(); + + // Static data + self::$errors = array( + //!! REMOVE ERR00 by auto-creating an array by default: + 'ERR00' => 'Not supported with only one source image.', + 'ERR01' => 'Source is not a GIF image.', + 'ERR02' => 'You have to give image resource variables, image URLs or image binary sources in the $frames array.', + 'ERR03' => 'Cannot make animation from animated GIF source.', + ); + } /** - * Create the GIF string (old: GIFEncoder) - * - * @param array $frames An array of frame: can be file paths, resource image variables, binary sources or image URLs - * @param array $durations An array containing the duration of each frame - * @param integer $loop Number of GIF loops before stopping animation (Set 0 to get an infinite loop) - * - * @return string The GIF string source - */ + * Create the GIF string (old: GIFEncoder) + * + * @param array $frames An array of frame: can be file paths, resource image variables, binary sources or image URLs + * @param array $durations An array containing the duration of each frame + * @param integer $loop Number of GIF loops before stopping animation (Set 0 to get an infinite loop) + * + * @return string The GIF string source + */ public function create($frames = array(), $durations = array(), $loop = 0) - { + { if (!is_array($frames) && !is_array($GIF_tim)) { - - throw new \Exception($this->version.': '.$this->errors['ERR00']); + throw new \Exception(VERSION.': '.self::$errors['ERR00']); } - + $this->loop = ($loop > -1) ? $loop : 0; $this->dis = 2; - + for ($i = 0; $i < count($frames); $i++) { if (is_resource($frames[$i])) { // Resource var - - $resourceImg = $frames[$i]; - - ob_start(); - imagegif($frames[$i]); - $this->frameSources[] = ob_get_contents(); - ob_end_clean(); - - } elseif (is_string($frames[$i])) { // File path or URL or Binary source code + + $resourceImg = $frames[$i]; + + ob_start(); + imagegif($frames[$i]); + $this->frameSources[] = ob_get_contents(); + ob_end_clean(); + + } elseif (is_string($frames[$i])) { // File path or URL or Binary source code - if (file_exists($frames[$i]) || filter_var($frames[$i], FILTER_VALIDATE_URL)) { // File path - - $frames[$i] = file_get_contents($frames[$i]); - } - - $resourceImg = imagecreatefromstring($frames[$i]); - - ob_start(); - imagegif($resourceImg); - $this->frameSources[] = ob_get_contents(); - ob_end_clean(); - + if (file_exists($frames[$i]) || filter_var($frames[$i], FILTER_VALIDATE_URL)) { // File path + $frames[$i] = file_get_contents($frames[$i]); + } + + $resourceImg = imagecreatefromstring($frames[$i]); + + ob_start(); + imagegif($resourceImg); + $this->frameSources[] = ob_get_contents(); + ob_end_clean(); + } else { // Fail - - throw new \Exception($this->version.': '.$this->errors['ERR02'].' ('.$mode.')'); + throw new \Exception(VERSION.': '.self::$errors['ERR02'].' ('.$mode.')'); } - - if ($i == 0) { - - $colour = imagecolortransparent($resourceImg); - } - + + if ($i == 0) { + $colour = imagecolortransparent($resourceImg); + } + if (substr($this->frameSources[$i], 0, 6) != 'GIF87a' && substr($this->frameSources[$i], 0, 6) != 'GIF89a') { - - throw new \Exception($this->version.': '.$i.' '.$this->errors['ERR01']); + throw new \Exception(VERSION.': '.$i.' '.self::$errors['ERR01']); } - + for ($j = (13 + 3 * (2 << (ord($this->frameSources[$i] { 10 }) & 0x07))), $k = TRUE; $k; $j++) { switch ($this->frameSources[$i] { $j }) { case '!': - + if ((substr($this->frameSources[$i], ($j + 3), 8)) == 'NETSCAPE') { - - throw new \Exception($this->version.': '.$this->errors['ERR03'].' ('.($i + 1).' source).'); + + throw new \Exception(VERSION.': '.self::$errors['ERR03'].' ('.($i + 1).' source).'); } - + break; - + case ';': - + $k = false; break; } } - - unset($resourceImg); + + unset($resourceImg); + }//for + + if (isset($colour)) { + $this->colour = $colour; + } else { + $red = $green = $blue = 0; + $this->colour = ($red > -1 && $green > -1 && $blue > -1) ? ($red | ($green << 8) | ($blue << 16)) : -1; } - - if (isset($colour)) { - - $this->colour = $colour; - - } else { - - $red = $green = $blue = 0; - $this->colour = ($red > -1 && $green > -1 && $blue > -1) ? ($red | ($green << 8) | ($blue << 16)) : -1; - } - + $this->gifAddHeader(); - + for ($i = 0; $i < count($this->frameSources); $i++) { $this->addGifFrames($i, $durations[$i]); } - + $this->gifAddFooter(); - - return $this->gif; + + return $this->gif; + } + + /** + * Get the final GIF image string (old: GetAnimation) + * + * @return string + */ + public function getGif() + { + return $this->gif; } - // Internals - // =================================================================================== - + // Internals + // =================================================================================== + /** - * Add the header gif string in its source (old: GIFAddHeader) - */ + * Reset and clean the current object (only used by the ctor. currently) + */ + public function reset() + { + $this->frameSources; + $this->gif = 'GIF89a'; // the GIF header + $this->imgBuilt = false; + $this->loop = 0; + $this->dis = 2; + $this->colour = -1; + } + + /** + * Add the header gif string in its source (old: GIFAddHeader) + */ public function gifAddHeader() - { + { $cmap = 0; if (ord($this->frameSources[0] { 10 }) & 0x80) { @@ -198,13 +216,13 @@ public function gifAddHeader() } /** - * Add the frame sources to the GIF string (old: GIFAddFrames) - * - * @param integer $i - * @param integer $d - */ + * Add the frame sources to the GIF string (old: GIFAddFrames) + * + * @param integer $i + * @param integer $d + */ public function addGifFrames($i, $d) - { + { $Locals_str = 13 + 3 * (2 << (ord($this->frameSources[ $i ] { 10 }) & 0x07)); $Locals_end = strlen($this->frameSources[$i]) - $Locals_str - 1; @@ -239,14 +257,14 @@ public function addGifFrames($i, $d) $Locals_img = substr($Locals_tmp, 8, 10); $Locals_tmp = substr($Locals_tmp, 18, strlen($Locals_tmp) - 18); - break; + break; case ',': $Locals_img = substr($Locals_tmp, 0, 10); $Locals_tmp = substr($Locals_tmp, 10, strlen($Locals_tmp) - 10); - break; + break; } if (ord($this->frameSources[$i] { 10 }) & 0x80 && $this->imgBuilt) { @@ -286,72 +304,47 @@ public function addGifFrames($i, $d) } /** - * Add the gif string footer char (old: GIFAddFooter) - */ + * Add the gif string footer char (old: GIFAddFooter) + */ public function gifAddFooter() - { + { $this->gif .= ';'; } /** - * Compare two block and return the version (old: GIFBlockCompare) - * - * @param string $globalBlock - * @param string $localBlock - * @param integer $length - * - * @return integer + * Compare two block and return the version (old: GIFBlockCompare) + * + * @param string $globalBlock + * @param string $localBlock + * @param integer $length + * + * @return integer */ public function gifBlockCompare($globalBlock, $localBlock, $length) - { + { for ($i = 0; $i < $length; $i++) { - if ($globalBlock { 3 * $i + 0 } != $localBlock { 3 * $i + 0 } || - $globalBlock { 3 * $i + 1 } != $localBlock { 3 * $i + 1 } || - $globalBlock { 3 * $i + 2 } != $localBlock { 3 * $i + 2 }) { + if ($globalBlock [ 3 * $i + 0 ] != $localBlock [ 3 * $i + 0 ] || + $globalBlock [ 3 * $i + 1 ] != $localBlock [ 3 * $i + 1 ] || + $globalBlock [ 3 * $i + 2 ] != $localBlock [ 3 * $i + 2 ]) { - return 0; + return 0; } } return 1; } - /** - * Encode an ASCII char into a string char (old: GIFWord) - * - * $param integer $char ASCII char - * - * @return string - */ - public function encodeAsciiToChar($char) - { - return (chr($char & 0xFF).chr(($char >> 8) & 0xFF)); - } - - /** - * Reset and clean the current object - */ - public function reset() - { - $this->frameSources; - $this->gif = 'GIF89a'; // the GIF header - $this->imgBuilt = false; - $this->loop = 0; - $this->dis = 2; - $this->colour = -1; - } - - // Getter / Setter - // =================================================================================== - - /** - * Get the final GIF image string (old: GetAnimation) - * - * @return string - */ - public function getGif() - { - return $this->gif; - } -} \ No newline at end of file +} + +/** + * Encode an ASCII char into a string char + * + * $param integer $char ASCII char + * + * @return string + */ +public function encodeAsciiToChar($char) +{ + return (chr($char & 0xFF).chr(($char >> 8) & 0xFF)); +} From 78d9f6efd21199f2fbf664f0f9a88d94050fbd33 Mon Sep 17 00:00:00 2001 From: lunakid Date: Thu, 24 Apr 2014 13:06:49 +0200 Subject: [PATCH 003/120] Fix encodeAsciiToChar() call (no $this-> any more). --- src/GifCreator/GifCreator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GifCreator/GifCreator.php b/src/GifCreator/GifCreator.php index 47d2547..057098b 100644 --- a/src/GifCreator/GifCreator.php +++ b/src/GifCreator/GifCreator.php @@ -211,7 +211,7 @@ public function gifAddHeader() $this->gif .= substr($this->frameSources[0], 6, 7); $this->gif .= substr($this->frameSources[0], 13, $cmap); - $this->gif .= "!\377\13NETSCAPE2.0\3\1".$this->encodeAsciiToChar($this->loop)."\0"; + $this->gif .= "!\377\13NETSCAPE2.0\3\1".encodeAsciiToChar($this->loop)."\0"; } } From 28fc1b4bb028d152240fd4350934b0468e905738 Mon Sep 17 00:00:00 2001 From: lunakid Date: Thu, 24 Apr 2014 13:19:25 +0200 Subject: [PATCH 004/120] Sync with name changes, added "Dependencies" --- README.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f9cabb3..8f74498 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,17 @@ NOTE: This is just a working copy (fork) of https://github.com/Sybio/GifCreator, -for some wording fixes (of mistakes inherited from the original [GIFEncoder](https://gist.github.com/allometry/1438842) from Laszlo Zsidi), minor code cosmetics, and customizations. All the rest below -is just the verbatim copy of Clément Guillemain's original README, unchanged (yet). +for some wording fixes (partly inherited from the original [GIFEncoder](https://gist.github.com/allometry/1438842) from Laszlo Zsidi), some code cosmetics, and (possibly upcoming) customizations. +All the rest below is just Clément Guillemain's original README (apart from +updating the names changed in this version). # ================================ -# GifCreator +# GifCreator\AnimGif # ================================ -GifCreator is a PHP class to create animated GIF from multiple images +AnimGif is a PHP class to create an animated GIF from multiple images. ### For what ? -This class helps you to create an animated GIF image: give multiple images and their duration and that's it ! +This class helps you create an animated GIF image: give multiple images and their duration and that's it! ### Usage @@ -31,7 +32,7 @@ $frames = array( $durations = array(40, 80, 40, 20); // Initialize and create the GIF ! -$gc = new GifCreator(); +$gc = new AnimGif(); $gc->create($frames, $durations, 5); ``` The 3rd parameter of create() method allows you to choose the number of loop of your animated gif before it stops. @@ -42,7 +43,7 @@ In the previous example, I chose 5 loops. Set 0 (zero) to get an infinite loop. You can now get the animated GIF binary: ```php -$gifBinary = $gc->getGif(); +$gifBinary = $gc->get(); ``` Then you can show it in the navigator: @@ -69,3 +70,8 @@ this class: https://github.com/Sybio/ImageWorkshop ### About The class reuses some part of code of "GIFEncoder.class.php" by László Zsidi (thanks to him). + +### Dependencies + +* PHP 5.3 (for namespace support) +* GD2 [!!?] From 440de99891904db2cb245cdd125b94a078f85b4d Mon Sep 17 00:00:00 2001 From: lunakid Date: Thu, 24 Apr 2014 13:21:22 +0200 Subject: [PATCH 005/120] Moved namespace from the title to the code samples. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8f74498..ed7b865 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ All the rest below is just Clément Guillemain's original README (apart from updating the names changed in this version). # ================================ -# GifCreator\AnimGif +# AnimGif # ================================ AnimGif is a PHP class to create an animated GIF from multiple images. @@ -32,7 +32,7 @@ $frames = array( $durations = array(40, 80, 40, 20); // Initialize and create the GIF ! -$gc = new AnimGif(); +$gc = new GifCreator\AnimGif(); $gc->create($frames, $durations, 5); ``` The 3rd parameter of create() method allows you to choose the number of loop of your animated gif before it stops. From 7f569c1ad1a81bf1acd30ce9890a4d996b6f2416 Mon Sep 17 00:00:00 2001 From: lunakid Date: Thu, 24 Apr 2014 13:32:22 +0200 Subject: [PATCH 006/120] Renamed class from GifCreator to AnimGif + Left the namespace as "GifCreator" (intentionally). + Renamed method getGif() to get(). + Changed {$i} indexes to [$i] in gifBlockCompare(). --- src/GifCreator/GifCreator.php | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/GifCreator/GifCreator.php b/src/GifCreator/GifCreator.php index 057098b..0c245a8 100644 --- a/src/GifCreator/GifCreator.php +++ b/src/GifCreator/GifCreator.php @@ -9,6 +9,9 @@ + Moved reset() closer up to the ctor. + Changed comments here & there. + Whitespaces: fixed some tab/space mismatch etc. ++ Changed {$i} indexes to [$i] in gifBlockCompare(). (Some more left.) ++ Renamed class to AnimGif (from GifCreator). ++ Renamed method getGif() to get(). */ /** @@ -22,7 +25,7 @@ namespace GifCreator; -class GifCreator +class AnimGif { /** * @var string The generated (binary) image @@ -77,7 +80,7 @@ public function __construct() } /** - * Create the GIF string (old: GIFEncoder) + * Create the GIF string * * @param array $frames An array of frame: can be file paths, resource image variables, binary sources or image URLs * @param array $durations An array containing the duration of each frame @@ -173,11 +176,11 @@ public function create($frames = array(), $durations = array(), $loop = 0) } /** - * Get the final GIF image string (old: GetAnimation) + * Get the final GIF image string * * @return string */ - public function getGif() + public function get() { return $this->gif; } @@ -199,7 +202,7 @@ public function reset() } /** - * Add the header gif string in its source (old: GIFAddHeader) + * Add the header gif string in its source */ public function gifAddHeader() { @@ -216,7 +219,7 @@ public function gifAddHeader() } /** - * Add the frame sources to the GIF string (old: GIFAddFrames) + * Add the frame sources to the GIF string * * @param integer $i * @param integer $d @@ -304,7 +307,7 @@ public function addGifFrames($i, $d) } /** - * Add the gif string footer char (old: GIFAddFooter) + * Add the gif string footer char */ public function gifAddFooter() { @@ -312,7 +315,7 @@ public function gifAddFooter() } /** - * Compare two block and return the version (old: GIFBlockCompare) + * Compare two block and return the version * * @param string $globalBlock * @param string $localBlock From cb7db12a6cb80847e963641f24ea4b4bdc310667 Mon Sep 17 00:00:00 2001 From: lunakid Date: Thu, 24 Apr 2014 13:42:18 +0200 Subject: [PATCH 007/120] Various small improvements. --- README.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ed7b865..272df38 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ NOTE: This is just a working copy (fork) of https://github.com/Sybio/GifCreator, for some wording fixes (partly inherited from the original [GIFEncoder](https://gist.github.com/allometry/1438842) from Laszlo Zsidi), some code cosmetics, and (possibly upcoming) customizations. -All the rest below is just Clément Guillemain's original README (apart from -updating the names changed in this version). +All the rest below is mostly just Clément Guillemain's original README (apart from +API name updates, slight wording changes, adding the Deps. section etc.). # ================================ # AnimGif @@ -32,8 +32,8 @@ $frames = array( $durations = array(40, 80, 40, 20); // Initialize and create the GIF ! -$gc = new GifCreator\AnimGif(); -$gc->create($frames, $durations, 5); +$anim = new GifCreator\AnimGif(); +$anim->create($frames, $durations, 5); ``` The 3rd parameter of create() method allows you to choose the number of loop of your animated gif before it stops. In the previous example, I chose 5 loops. Set 0 (zero) to get an infinite loop. @@ -43,10 +43,11 @@ In the previous example, I chose 5 loops. Set 0 (zero) to get an infinite loop. You can now get the animated GIF binary: ```php -$gifBinary = $gc->get(); +$gifBinary = $anim->get(); ``` -Then you can show it in the navigator: +**3 - Use it:** +Then you can send it to the browser: ```php header('Content-type: image/gif'); @@ -55,7 +56,7 @@ echo $gifBinary; exit; ``` -Or save it in a folder as a GIF: +Or save it as a GIF file: ```php file_put_contents('/myfolder/animated_picture.gif', $gifBinary); @@ -74,4 +75,4 @@ The class reuses some part of code of "GIFEncoder.class.php" by László Zsidi ( ### Dependencies * PHP 5.3 (for namespace support) -* GD2 [!!?] +* GD (imagecreatefromstring, imagecolortransparent etc.) From 1e21c503e385e4adc25728986db7510ae5088891 Mon Sep 17 00:00:00 2001 From: lunakid Date: Thu, 24 Apr 2014 13:43:28 +0200 Subject: [PATCH 008/120] Formatting fix. (Ehh... How can I do commit --amend here?) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 272df38..d61ea49 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ $gifBinary = $anim->get(); ``` **3 - Use it:** + Then you can send it to the browser: ```php From 1e6e54150046b57f10ad80fafd43b27c19598af6 Mon Sep 17 00:00:00 2001 From: lunakid Date: Thu, 24 Apr 2014 13:44:58 +0200 Subject: [PATCH 009/120] Minor cosmetics. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d61ea49..c79bcbe 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ API name updates, slight wording changes, adding the Deps. section etc.). AnimGif is a PHP class to create an animated GIF from multiple images. -### For what ? +### For what? This class helps you create an animated GIF image: give multiple images and their duration and that's it! From 43befb1e2bf4307235c9e483801863bf02e43954 Mon Sep 17 00:00:00 2001 From: lunakid Date: Thu, 24 Apr 2014 13:48:11 +0200 Subject: [PATCH 010/120] Removed confusing "working copy" stuff etc. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c79bcbe..1910178 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -NOTE: This is just a working copy (fork) of https://github.com/Sybio/GifCreator, -for some wording fixes (partly inherited from the original [GIFEncoder](https://gist.github.com/allometry/1438842) from Laszlo Zsidi), some code cosmetics, and (possibly upcoming) customizations. +NOTE: This is mostly just a "stylistic" fork of the nice https://github.com/Sybio/GifCreator, +for some code cosmetics, class rename, some wording fixes (partly inherited from the original [GIFEncoder](https://gist.github.com/allometry/1438842) from Laszlo Zsidi), and (possibly upcoming) customizations. All the rest below is mostly just Clément Guillemain's original README (apart from API name updates, slight wording changes, adding the Deps. section etc.). From 0320fa441858e6bc262222390ced3709103f9ba7 Mon Sep 17 00:00:00 2001 From: lunakid Date: Thu, 24 Apr 2014 13:49:58 +0200 Subject: [PATCH 011/120] Wording... --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1910178..767adac 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ NOTE: This is mostly just a "stylistic" fork of the nice https://github.com/Sybio/GifCreator, -for some code cosmetics, class rename, some wording fixes (partly inherited from the original [GIFEncoder](https://gist.github.com/allometry/1438842) from Laszlo Zsidi), and (possibly upcoming) customizations. +for some code cosmetics (incl. some API name changes), some wording fixes (partly inherited from the original [GIFEncoder](https://gist.github.com/allometry/1438842) from Laszlo Zsidi), and (possibly upcoming) customizations. All the rest below is mostly just Clément Guillemain's original README (apart from API name updates, slight wording changes, adding the Deps. section etc.). From 954f06d1704953ada0df9faf2b01866882f6c0a8 Mon Sep 17 00:00:00 2001 From: lunakid Date: Thu, 24 Apr 2014 13:58:18 +0200 Subject: [PATCH 012/120] Changed "About" to "Credits" + small formatting craps --- README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 767adac..c4e9f8c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ NOTE: This is mostly just a "stylistic" fork of the nice https://github.com/Sybio/GifCreator, -for some code cosmetics (incl. some API name changes), some wording fixes (partly inherited from the original [GIFEncoder](https://gist.github.com/allometry/1438842) from Laszlo Zsidi), and (possibly upcoming) customizations. -All the rest below is mostly just Clément Guillemain's original README (apart from -API name updates, slight wording changes, adding the Deps. section etc.). +for some code cosmetics (incl. some API name changes), some wording fixes (partly inherited from the original [GIFEncoder](https://gist.github.com/allometry/1438842) from Laci Zsidi), and (possibly upcoming) customizations. +The rest below is mostly just Clément Guillemain's README (apart from API name updates, +slight wording changes, adding the Deps. & Credits sections etc.). # ================================ # AnimGif @@ -69,11 +69,12 @@ file_put_contents('/myfolder/animated_picture.gif', $gifBinary); - The dimensions of the generated GIF are based on the first frame. If you need to resize your frames to get the same dimension, you can use this class: https://github.com/Sybio/ImageWorkshop -### About +### Credits -The class reuses some part of code of "GIFEncoder.class.php" by László Zsidi (thanks to him). +* László Zsidi: Important parts of his "GIFEncoder.class.php" by have been reused. (Thanks, Laci!) +* Clément Guillemain: for the very handy, redesigned (& "classified") API, extensions and nice docs. ### Dependencies * PHP 5.3 (for namespace support) -* GD (imagecreatefromstring, imagecolortransparent etc.) +* GD (`imagecreatefromstring`, `imagecolortransparent` etc.) From 0eb720568300b645681836229a9dbf3e7d67bff7 Mon Sep 17 00:00:00 2001 From: lunakid Date: Thu, 24 Apr 2014 14:00:10 +0200 Subject: [PATCH 013/120] Moved Credits down, Dependencies up --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c4e9f8c..a856c6d 100644 --- a/README.md +++ b/README.md @@ -69,12 +69,12 @@ file_put_contents('/myfolder/animated_picture.gif', $gifBinary); - The dimensions of the generated GIF are based on the first frame. If you need to resize your frames to get the same dimension, you can use this class: https://github.com/Sybio/ImageWorkshop -### Credits - -* László Zsidi: Important parts of his "GIFEncoder.class.php" by have been reused. (Thanks, Laci!) -* Clément Guillemain: for the very handy, redesigned (& "classified") API, extensions and nice docs. - ### Dependencies * PHP 5.3 (for namespace support) * GD (`imagecreatefromstring`, `imagecolortransparent` etc.) + +### Credits + +* László Zsidi: Important parts of his "GIFEncoder.class.php" by have been reused. (Thanks, Laci!) +* Clément Guillemain: for the very handy, redesigned (& "classified") API, extensions and nice docs. From fd8ca5fc2692a8acb5dc346d2c4676e8d84973fe Mon Sep 17 00:00:00 2001 From: lunakid Date: Thu, 24 Apr 2014 14:01:35 +0200 Subject: [PATCH 014/120] Typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a856c6d..a75d81d 100644 --- a/README.md +++ b/README.md @@ -76,5 +76,5 @@ this class: https://github.com/Sybio/ImageWorkshop ### Credits -* László Zsidi: Important parts of his "GIFEncoder.class.php" by have been reused. (Thanks, Laci!) -* Clément Guillemain: for the very handy, redesigned (& "classified") API, extensions and nice docs. +* László Zsidi: Important parts of his "GIFEncoder.class.php" have been reused. (Thanks, Laci!) +* Clément Guillemain: for the very handy, redesigned (& "classified") API, extensions and nice docs! From 581ce6ff2e5f9eabc6bbfb94f76fa3b840bf5dc9 Mon Sep 17 00:00:00 2001 From: lunakid Date: Thu, 24 Apr 2014 14:18:28 +0200 Subject: [PATCH 015/120] Messed with it -- highly suspect it broken now! ! Haven't (and probably won't ever!) test the current version at all! ? Move to PSR-4 anyway? (We depend on PHP 5.3+ already.) --- composer.json | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 9d98c23..b28eddf 100644 --- a/composer.json +++ b/composer.json @@ -1,21 +1,28 @@ { - "name": "sybio/gif-creator", + "name": "lunakid/anim-gif", "type": "library", - "description": "PHP class that creates animated GIF from multiple images", + "description": "PHP class to create an animated GIF from multiple images", "keywords": ["gif", "animated", "creation", "encode", "PHP"], - "homepage": "https://github.com/Sybio/GifCreator", + "homepage": "https://github.com/lunakid/AnimGif", "license": "MIT", "authors": [ { "name": "Clément Guillemain", "homepage": "http://clementguillemain.fr", "role": "Developer / Freelancer" + }, + { + "name": "Szabolcs Szász", + "homepage": "http://github.com/lunakid", + "role": "Developer / Freelancer" } ], "require": { "php": ">=5.3.0" }, "autoload": { - "psr-0": { "GifCreator": "src" } + "psr-0": { + "GifCreator": "src", + } } -} \ No newline at end of file +} From 26846209e399f87f19e3ec023e2d73234b4ac68d Mon Sep 17 00:00:00 2001 From: lunakid Date: Thu, 24 Apr 2014 14:22:36 +0200 Subject: [PATCH 016/120] Renamed the source file (from GifCreator.php) --- src/GifCreator/{GifCreator.php => AnimGif.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/GifCreator/{GifCreator.php => AnimGif.php} (100%) diff --git a/src/GifCreator/GifCreator.php b/src/GifCreator/AnimGif.php similarity index 100% rename from src/GifCreator/GifCreator.php rename to src/GifCreator/AnimGif.php From 6f4be7e1fca8f8cae53b6076aa8f8d35191a8a7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Thu, 24 Apr 2014 16:32:50 +0200 Subject: [PATCH 017/120] Moved the `namespace` stmt. above `define()` "Fatal error: Namespace declaration statement has to be the very first statement in the script" --- src/GifCreator/AnimGif.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 0c245a8..d68a553 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -1,5 +1,4 @@ version a define (VERSION). @@ -23,8 +22,11 @@ * @copyright Clément Guillemain, Szabolcs Szász */ + namespace GifCreator; +define(VERSION, '1.1-lunakid'); + class AnimGif { /** From ebe0f8afd4447a6ae62413afd4f7a8caf0336550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Thu, 24 Apr 2014 16:34:48 +0200 Subject: [PATCH 018/120] Cut leftover "public" from encodeAsciiToChar() Parse error: syntax error, unexpected T_PUBLIC in P:\JOB+CONTRACT_\Bulesz\WeatherCert\sys\common\animgif.php on line 352 --- src/GifCreator/AnimGif.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index d68a553..fd50d70 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -349,7 +349,7 @@ public function gifBlockCompare($globalBlock, $localBlock, $length) * * @return string */ -public function encodeAsciiToChar($char) +function encodeAsciiToChar($char) { return (chr($char & 0xFF).chr(($char >> 8) & 0xFF)); } From 0e3734f6ad3070c10d107f7e5f2342bb0cf4b91a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Thu, 24 Apr 2014 20:28:15 +0200 Subject: [PATCH 019/120] Prettified link to GifCreator etc. --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a75d81d..af80605 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ -NOTE: This is mostly just a "stylistic" fork of the nice https://github.com/Sybio/GifCreator, -for some code cosmetics (incl. some API name changes), some wording fixes (partly inherited from the original [GIFEncoder](https://gist.github.com/allometry/1438842) from Laci Zsidi), and (possibly upcoming) customizations. -The rest below is mostly just Clément Guillemain's README (apart from API name updates, -slight wording changes, adding the Deps. & Credits sections etc.). +NOTE: This is mostly just a "stylistic" fork of Clément Guillemain's nice [GifCreator class](https://github.com/Sybio/GifCreator), for some code cosmetics (incl. some API name changes), +some wording fixes (partly inherited from the original [GIFEncoder](https://gist.github.com/allometry/1438842) +from Laci Zsidi), and (possibly upcoming) customizations. +The rest below is mostly just the original README (apart from API name updates, slight wording changes, adding the +Dependencies & Credits sections etc.). # ================================ # AnimGif From d11d02f91e057dbf18116e91d47c5c50878b9d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Thu, 24 Apr 2014 20:36:14 +0200 Subject: [PATCH 020/120] Fix leftover $GIF_tim name in create() --- src/GifCreator/AnimGif.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index fd50d70..296943b 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -1,6 +1,13 @@ version a define (VERSION). + Made $this->errors really static (self::$errors). + Moved encodeAsciiToChar() out from the class to the namespace root as a general utility fn. @@ -9,8 +16,6 @@ + Changed comments here & there. + Whitespaces: fixed some tab/space mismatch etc. + Changed {$i} indexes to [$i] in gifBlockCompare(). (Some more left.) -+ Renamed class to AnimGif (from GifCreator). -+ Renamed method getGif() to get(). */ /** @@ -73,7 +78,6 @@ public function __construct() // Static data self::$errors = array( - //!! REMOVE ERR00 by auto-creating an array by default: 'ERR00' => 'Not supported with only one source image.', 'ERR01' => 'Source is not a GIF image.', 'ERR02' => 'You have to give image resource variables, image URLs or image binary sources in the $frames array.', @@ -92,7 +96,7 @@ public function __construct() */ public function create($frames = array(), $durations = array(), $loop = 0) { - if (!is_array($frames) && !is_array($GIF_tim)) { + if (!is_array($frames) && !is_array($durations)) { throw new \Exception(VERSION.': '.self::$errors['ERR00']); } From 681e9f4eeb0400066099a64a78cce305091e18ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Thu, 24 Apr 2014 20:45:33 +0200 Subject: [PATCH 021/120] Support even timing without an array, fix ERR00. + Separate ERR00 from $durations not being an array. + Support uniform timing without an array. --- src/GifCreator/AnimGif.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 296943b..8f353c6 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -2,9 +2,11 @@ /* [!!UNTESTED!!] CHANGES by lunakid: TODO: -! Do support uniform timing without an array. -! Remove ERR00 by auto-creating an 1-element array by default. +! ERR01 is 'Source is not a GIF image.', but there's a png in the examples! + -> Do support non-GIF files! DONE: ++ Support uniform timing without an array. ++ Separate ERR00 from $durations not being an array. + Fix leftover $GIF_tim name in create(). + Renamed method getGif() to get(). + Renamed class to AnimGif (from GifCreator). @@ -78,10 +80,10 @@ public function __construct() // Static data self::$errors = array( - 'ERR00' => 'Not supported with only one source image.', + 'ERR00' => 'Cannot make animation from a single frame.', 'ERR01' => 'Source is not a GIF image.', 'ERR02' => 'You have to give image resource variables, image URLs or image binary sources in the $frames array.', - 'ERR03' => 'Cannot make animation from animated GIF source.', + 'ERR03' => 'Cannot make animation from animated GIF.', ); } @@ -96,7 +98,7 @@ public function __construct() */ public function create($frames = array(), $durations = array(), $loop = 0) { - if (!is_array($frames) && !is_array($durations)) { + if (!is_array($frames)) { throw new \Exception(VERSION.': '.self::$errors['ERR00']); } @@ -173,7 +175,7 @@ public function create($frames = array(), $durations = array(), $loop = 0) for ($i = 0; $i < count($this->frameSources); $i++) { - $this->addGifFrames($i, $durations[$i]); + $this->addGifFrames($i, is_array($durations) ? $durations[$i] : $durations); } $this->gifAddFooter(); From 0a733c68e4d5231e02d0375f2381c5a473b90cc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Thu, 24 Apr 2014 20:52:54 +0200 Subject: [PATCH 022/120] Added example for even timing & infinite loop default --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index af80605..45431ef 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ NOTE: This is mostly just a "stylistic" fork of Clément Guillemain's nice [GifCreator class](https://github.com/Sybio/GifCreator), for some code cosmetics (incl. some API name changes), some wording fixes (partly inherited from the original [GIFEncoder](https://gist.github.com/allometry/1438842) from Laci Zsidi), and (possibly upcoming) customizations. -The rest below is mostly just the original README (apart from API name updates, slight wording changes, adding the -Dependencies & Credits sections etc.). +(The rest below is mostly the original README, apart from API changes, slight wording fixes, adding the +Dependencies & Credits sections etc.) # ================================ # AnimGif @@ -29,15 +29,15 @@ $frames = array( 'http://thisisafakedomain.com/images/pic4.jpg', // URL ); -// Create an array containing the duration (in millisecond) of each frames (in order too) +// Create an (optional) array containing the duration (in milliseconds) of each frame (in order too) $durations = array(40, 80, 40, 20); // Initialize and create the GIF ! $anim = new GifCreator\AnimGif(); -$anim->create($frames, $durations, 5); +$anim->create($frames, $durations, 5); // or just create($frames, 40) for an even 40ms delay ``` -The 3rd parameter of create() method allows you to choose the number of loop of your animated gif before it stops. -In the previous example, I chose 5 loops. Set 0 (zero) to get an infinite loop. +The 3rd parameter of create() allows you to set the number of loops of your animated gif before it stops. +In the previous example, I chose 5 loops. Omit or set to 0 (zero) for an infinite loop. **2 - Get the result:** From b29c9f12ac2b6fc8eebca8a9960a26dd84e9c7b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Thu, 24 Apr 2014 20:59:51 +0200 Subject: [PATCH 023/120] $duration default = 40ms, $frames no longer optional in create() + $duration now has a meaningful default in create(). + $frames was incorrectly made an optional arg. of create(). --- src/GifCreator/AnimGif.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 8f353c6..868a732 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -5,6 +5,8 @@ ! ERR01 is 'Source is not a GIF image.', but there's a png in the examples! -> Do support non-GIF files! DONE: ++ $duration now has a meaningful default in create(). ++ $frames was incorrectly made an optional arg. of create(). + Support uniform timing without an array. + Separate ERR00 from $durations not being an array. + Fix leftover $GIF_tim name in create(). @@ -91,12 +93,12 @@ public function __construct() * Create the GIF string * * @param array $frames An array of frame: can be file paths, resource image variables, binary sources or image URLs - * @param array $durations An array containing the duration of each frame + * @param array|number $durations The duration (in ms) of each frame, or a single integer for each one. * @param integer $loop Number of GIF loops before stopping animation (Set 0 to get an infinite loop) * * @return string The GIF string source */ - public function create($frames = array(), $durations = array(), $loop = 0) + public function create($frames, $durations = 40, $loop = 0) { if (!is_array($frames)) { throw new \Exception(VERSION.': '.self::$errors['ERR00']); From 37f7d740970b00876de1e022791f8c42869e168b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Thu, 24 Apr 2014 21:15:09 +0200 Subject: [PATCH 024/120] Iterate with foreach in create(), leftover $mode deleted. + create() should iterate $frames with foreach() not for assuming direct indexes from 0 to < count. (The array keys can be anything, and should not affect the results.) + Removed unused $mode from reporting ERR02. --- src/GifCreator/AnimGif.php | 41 +++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 868a732..7e8f970 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -5,6 +5,10 @@ ! ERR01 is 'Source is not a GIF image.', but there's a png in the examples! -> Do support non-GIF files! DONE: ++ create() should iterate $frames with foreach() not for assuming direct + indexes from 0 to < count. + (The array keys can be anything, and should not affect the results.) ++ Removed unused $mode from reporting ERR02. + $duration now has a meaningful default in create(). + $frames was incorrectly made an optional arg. of create(). + Support uniform timing without an array. @@ -107,24 +111,25 @@ public function create($frames, $durations = 40, $loop = 0) $this->loop = ($loop > -1) ? $loop : 0; $this->dis = 2; - for ($i = 0; $i < count($frames); $i++) { + $i = 0; + foreach ($frames as $frame) { - if (is_resource($frames[$i])) { // Resource var + if (is_resource($frame)) { // Resource var - $resourceImg = $frames[$i]; + $resourceImg = $frame; ob_start(); - imagegif($frames[$i]); + imagegif($frame); $this->frameSources[] = ob_get_contents(); ob_end_clean(); - } elseif (is_string($frames[$i])) { // File path or URL or Binary source code + } elseif (is_string($frame)) { // File path or URL or Binary source code - if (file_exists($frames[$i]) || filter_var($frames[$i], FILTER_VALIDATE_URL)) { // File path - $frames[$i] = file_get_contents($frames[$i]); + if (file_exists($frame]) || filter_var($frame, FILTER_VALIDATE_URL)) { // File path + $frame = file_get_contents($frame); } - $resourceImg = imagecreatefromstring($frames[$i]); + $resourceImg = imagecreatefromstring($frame); ob_start(); imagegif($resourceImg); @@ -132,7 +137,7 @@ public function create($frames, $durations = 40, $loop = 0) ob_end_clean(); } else { // Fail - throw new \Exception(VERSION.': '.self::$errors['ERR02'].' ('.$mode.')'); + throw new \Exception(VERSION.': '.self::$errors['ERR02']); } if ($i == 0) { @@ -148,23 +153,23 @@ public function create($frames, $durations = 40, $loop = 0) switch ($this->frameSources[$i] { $j }) { case '!': - - if ((substr($this->frameSources[$i], ($j + 3), 8)) == 'NETSCAPE') { + if ((substr($this->frameSources[$i], ($j + 3), 8)) == 'NETSCAPE') { - throw new \Exception(VERSION.': '.self::$errors['ERR03'].' ('.($i + 1).' source).'); + throw new \Exception(VERSION.': '.self::$errors['ERR03'].' ('.($i + 1).' source).'); } - break; + break; case ';': - - $k = false; - break; + $k = false; + break; } } unset($resourceImg); - }//for + + ++$i; + }//foreach if (isset($colour)) { $this->colour = $colour; @@ -176,7 +181,7 @@ public function create($frames, $durations = 40, $loop = 0) $this->gifAddHeader(); for ($i = 0; $i < count($this->frameSources); $i++) { - + $this->addGifFrames($i, is_array($durations) ? $durations[$i] : $durations); } From 5982da6ad7d3bd5c4739b7b15525226fdd572566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Thu, 24 Apr 2014 21:16:59 +0200 Subject: [PATCH 025/120] Typos --- src/GifCreator/AnimGif.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 7e8f970..1960b22 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -2,7 +2,7 @@ /* [!!UNTESTED!!] CHANGES by lunakid: TODO: -! ERR01 is 'Source is not a GIF image.', but there's a png in the examples! +! ERR01 is 'Source is not a GIF image.', but there's a .png in the examples! -> Do support non-GIF files! DONE: + create() should iterate $frames with foreach() not for assuming direct @@ -125,7 +125,7 @@ public function create($frames, $durations = 40, $loop = 0) } elseif (is_string($frame)) { // File path or URL or Binary source code - if (file_exists($frame]) || filter_var($frame, FILTER_VALIDATE_URL)) { // File path + if (file_exists($frame) || filter_var($frame, FILTER_VALIDATE_URL)) { // File path $frame = file_get_contents($frame); } From cb9f997ac20462b785e5316979f1dcba69708300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Thu, 24 Apr 2014 21:23:36 +0200 Subject: [PATCH 026/120] Added todo for fixing broken "direct GIF" example. --- src/GifCreator/AnimGif.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 1960b22..4ba215f 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -1,9 +1,10 @@ Do support non-GIF files! + -> It does support non-GIF files actually! DONE: + create() should iterate $frames with foreach() not for assuming direct indexes from 0 to < count. From 73b56311bd06f8acf4a2e6774cd96e55ae84c4ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Thu, 24 Apr 2014 21:25:01 +0200 Subject: [PATCH 027/120] Todo added for wrong(?) anim delay --- src/GifCreator/AnimGif.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 4ba215f..7e2768e 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -2,6 +2,7 @@ /* CHANGES by lunakid: TODO: +! Anim delay does not seem to be 40 ms by default... ! The raw GIF return example is broken in the README. ! ERR01 is 'Source is not a GIF image.', but there's a .png in the examples! -> It does support non-GIF files actually! From 44b01ca18d011e7419e250a2cbce2331f29adb3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 00:08:03 +0200 Subject: [PATCH 028/120] Cosmetics, GIF example OK. --- src/GifCreator/AnimGif.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 7e2768e..c46d14b 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -3,10 +3,11 @@ /* CHANGES by lunakid: TODO: ! Anim delay does not seem to be 40 ms by default... -! The raw GIF return example is broken in the README. ! ERR01 is 'Source is not a GIF image.', but there's a .png in the examples! -> It does support non-GIF files actually! DONE: ++ The raw GIF return example is broken in the README. + (It was not caused by this code.) + create() should iterate $frames with foreach() not for assuming direct indexes from 0 to < count. (The array keys can be anything, and should not affect the results.) @@ -251,7 +252,7 @@ public function addGifFrames($i, $d) $Global_len = 2 << (ord($this->frameSources[0 ] { 10 }) & 0x07); $Locals_len = 2 << (ord($this->frameSources[$i] { 10 }) & 0x07); - $Global_rgb = substr($this->frameSources[0], 13, 3 * (2 << (ord($this->frameSources[0] { 10 }) & 0x07))); + $Global_rgb = substr($this->frameSources[ 0], 13, 3 * (2 << (ord($this->frameSources[ 0] { 10 }) & 0x07))); $Locals_rgb = substr($this->frameSources[$i], 13, 3 * (2 << (ord($this->frameSources[$i] { 10 }) & 0x07))); $Locals_ext = "!\xF9\x04".chr(($this->dis << 2) + 0).chr(($d >> 0 ) & 0xFF).chr(($d >> 8) & 0xFF)."\x0\x0"; From 74e33d7b909161c50f20476a0c04fb39e19792af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 00:10:06 +0200 Subject: [PATCH 029/120] Removed redundant & non-std. Content-Disposition header --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 45431ef..f94bc52 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,6 @@ Then you can send it to the browser: ```php header('Content-type: image/gif'); -header('Content-Disposition: filename="butterfly.gif"'); echo $gifBinary; exit; ``` From da6c88e2676e9e0a4ab5a7721a22e82eced2ab34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 00:17:30 +0200 Subject: [PATCH 030/120] Fix ERR01 ("Resource is not a GIF image.") --- src/GifCreator/AnimGif.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index c46d14b..874c13f 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -3,11 +3,13 @@ /* CHANGES by lunakid: TODO: ! Anim delay does not seem to be 40 ms by default... -! ERR01 is 'Source is not a GIF image.', but there's a .png in the examples! - -> It does support non-GIF files actually! DONE: ++ Fix ERR01 "Source is not a GIF image.": there's a .png in the examples! + -> And it does support non-GIF files actually. + Moved the error check to resource inputs only, and changed it to + "Resource is not a GIF image.". + The raw GIF return example is broken in the README. - (It was not caused by this code.) + (It was not caused by this code.) + create() should iterate $frames with foreach() not for assuming direct indexes from 0 to < count. (The array keys can be anything, and should not affect the results.) @@ -90,7 +92,7 @@ public function __construct() // Static data self::$errors = array( 'ERR00' => 'Cannot make animation from a single frame.', - 'ERR01' => 'Source is not a GIF image.', + 'ERR01' => 'Resource is not a GIF image.', 'ERR02' => 'You have to give image resource variables, image URLs or image binary sources in the $frames array.', 'ERR03' => 'Cannot make animation from animated GIF.', ); @@ -126,6 +128,10 @@ public function create($frames, $durations = 40, $loop = 0) $this->frameSources[] = ob_get_contents(); ob_end_clean(); + if (substr($this->frameSources[$i], 0, 6) != 'GIF87a' && substr($this->frameSources[$i], 0, 6) != 'GIF89a') { + throw new \Exception(VERSION.': '.$i.' '.self::$errors['ERR01']); + } + } elseif (is_string($frame)) { // File path or URL or Binary source code if (file_exists($frame) || filter_var($frame, FILTER_VALIDATE_URL)) { // File path @@ -147,10 +153,6 @@ public function create($frames, $durations = 40, $loop = 0) $colour = imagecolortransparent($resourceImg); } - if (substr($this->frameSources[$i], 0, 6) != 'GIF87a' && substr($this->frameSources[$i], 0, 6) != 'GIF89a') { - throw new \Exception(VERSION.': '.$i.' '.self::$errors['ERR01']); - } - for ($j = (13 + 3 * (2 << (ord($this->frameSources[$i] { 10 }) & 0x07))), $k = TRUE; $k; $j++) { switch ($this->frameSources[$i] { $j }) { From bb1eccec8e2f07eb6f67adb23a2e53ade34044bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 00:19:04 +0200 Subject: [PATCH 031/120] Updated the GitHub URL after the repo rename --- src/GifCreator/AnimGif.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 874c13f..1f56589 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -34,13 +34,12 @@ /** * Create an animated GIF from multiple images * - * @link https://github.com/lunakid/GifCreator + * @link https://github.com/lunakid/AnimGif * @author Sybio (Clément Guillemain / @Sybio01), lunakid (@GitHub, @Gmail, @SO etc.) * @license http://opensource.org/licenses/gpl-license.php GNU Public License * @copyright Clément Guillemain, Szabolcs Szász */ - namespace GifCreator; define(VERSION, '1.1-lunakid'); From 92fb5b4c6aed61338be7d4494473a9a36708b074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 00:20:30 +0200 Subject: [PATCH 032/120] Call it "version 1.1", not "1.1-lunakid" --- src/GifCreator/AnimGif.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 1f56589..ad26a84 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -42,7 +42,7 @@ namespace GifCreator; -define(VERSION, '1.1-lunakid'); +define(VERSION, '1.1'); class AnimGif { From a785d484995799daa4e972a2fc9458bb0f6ec2f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 00:22:14 +0200 Subject: [PATCH 033/120] Cosmetics --- src/GifCreator/AnimGif.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index ad26a84..fa4960d 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -18,7 +18,7 @@ + $frames was incorrectly made an optional arg. of create(). + Support uniform timing without an array. + Separate ERR00 from $durations not being an array. -+ Fix leftover $GIF_tim name in create(). ++ Fix leftover $GIF_tim in create(). + Renamed method getGif() to get(). + Renamed class to AnimGif (from GifCreator). + Made $this->version a define (VERSION). From 9d419167f4986b7bfb70fc4123d3a630a9a800de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 00:30:29 +0200 Subject: [PATCH 034/120] Fork-note updated --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f94bc52..f5a1f86 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -NOTE: This is mostly just a "stylistic" fork of Clément Guillemain's nice [GifCreator class](https://github.com/Sybio/GifCreator), for some code cosmetics (incl. some API name changes), -some wording fixes (partly inherited from the original [GIFEncoder](https://gist.github.com/allometry/1438842) -from Laci Zsidi), and (possibly upcoming) customizations. +NOTE: This is mostly a "stylistic" fork of Clément Guillemain's nice [GifCreator class](https://github.com/Sybio/GifCreator), for code cosmetics, some API changes (e.g. renaming the class), +wording fixes (partly inherited from the original [GIFEncoder](https://gist.github.com/allometry/1438842) +from Laci Zsidi), minor corrections & improvements etc. (The rest below is mostly the original README, apart from API changes, slight wording fixes, adding the Dependencies & Credits sections etc.) From adbf1c2353c894732e6508625e12328226feb7dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 00:34:14 +0200 Subject: [PATCH 035/120] Update README.md --- README.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f5a1f86..1adef7c 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,14 @@ -NOTE: This is mostly a "stylistic" fork of Clément Guillemain's nice [GifCreator class](https://github.com/Sybio/GifCreator), for code cosmetics, some API changes (e.g. renaming the class), +*NOTE: This is mostly a "stylistic" fork of Clément Guillemain's nice [GifCreator class](https://github.com/Sybio/GifCreator), for code cosmetics, some API changes (e.g. renaming the class), wording fixes (partly inherited from the original [GIFEncoder](https://gist.github.com/allometry/1438842) -from Laci Zsidi), minor corrections & improvements etc. -(The rest below is mostly the original README, apart from API changes, slight wording fixes, adding the -Dependencies & Credits sections etc.) +from Laci Zsidi), minor corrections & improvements etc.* # ================================ # AnimGif # ================================ AnimGif is a PHP class to create an animated GIF from multiple images. +Just list a few images (and optionally their durations) -- and that's it! -### For what? - -This class helps you create an animated GIF image: give multiple images and their duration and that's it! ### Usage From e3999a053465feeb2d1206e43614c479db9eac7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 00:38:07 +0200 Subject: [PATCH 036/120] Small fixes --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1adef7c..acc3dc5 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ from Laci Zsidi), minor corrections & improvements etc.* # ================================ AnimGif is a PHP class to create an animated GIF from multiple images. + Just list a few images (and optionally their durations) -- and that's it! @@ -61,14 +62,14 @@ file_put_contents('/myfolder/animated_picture.gif', $gifBinary); ### Behavior -- The transparency is based on the first given frame. It will be saved only if you give multiple frames with same transparent background. +- The transparency is based on the first given frame. It will be saved only if you give multiple frames with the same transparent background. - The dimensions of the generated GIF are based on the first frame. If you need to resize your frames to get the same dimension, you can use -this class: https://github.com/Sybio/ImageWorkshop +this class: https://github.com/Sybio/ImageWorkshop. ### Dependencies * PHP 5.3 (for namespace support) -* GD (`imagecreatefromstring`, `imagecolortransparent` etc.) +* GD (`imagecreatefromstring`, `imagegif`, `imagecolortransparent`) ### Credits From a88de0a80ac972e154bdfd9da796c8d23104b5e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 00:40:53 +0200 Subject: [PATCH 037/120] Better descr. line --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index acc3dc5..d5b40cc 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,7 @@ from Laci Zsidi), minor corrections & improvements etc.* # AnimGif # ================================ -AnimGif is a PHP class to create an animated GIF from multiple images. - -Just list a few images (and optionally their durations) -- and that's it! +AnimGif is a PHP class to create an animated GIF -- just list the source images, and that's it! ### Usage From f8352a9bdfe6193f2e8c4eee2a616346f4a0f6af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 00:48:13 +0200 Subject: [PATCH 038/120] Examples extended, explanations less verbose. --- README.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d5b40cc..2c4540e 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,8 @@ AnimGif is a PHP class to create an animated GIF -- just list the source images, **1 - Creation:** ```php -// Create an array containing file paths, resource var (initialized with imagecreatefromXXX), -// image URLs or even binary code from image files. -// All sorted in order to appear. +// Create an array containing file paths, resource vars (initialized with imagecreatefromXXX), +// image URLs or even binary code from image files. (All in the order as they should appear.) $frames = array( imagecreatefrompng("/../images/pic1.png"), // Resource var "/../images/pic2.png", // Image file path @@ -24,15 +23,19 @@ $frames = array( 'http://thisisafakedomain.com/images/pic4.jpg', // URL ); -// Create an (optional) array containing the duration (in milliseconds) of each frame (in order too) +// Optionally, create an array containing the duration (in milliseconds) of each frame $durations = array(40, 80, 40, 20); -// Initialize and create the GIF ! +// Initialize and create the GIF! $anim = new GifCreator\AnimGif(); -$anim->create($frames, $durations, 5); // or just create($frames, 40) for an even 40ms delay +$anim->create($frames, $durations); + +// Or, for just a default even 40ms delay: +//$anim->create($frames); + +// Or, for 5 repeats & then stop: +//$anim->create($frames, $durations, 5); // default: infinite looping ``` -The 3rd parameter of create() allows you to set the number of loops of your animated gif before it stops. -In the previous example, I chose 5 loops. Omit or set to 0 (zero) for an infinite loop. **2 - Get the result:** From 9cbbc1d4b331c8e75627d07c755995d9cd4dd29c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 00:56:01 +0200 Subject: [PATCH 039/120] Some styling --- README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2c4540e..a553c50 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,14 @@ wording fixes (partly inherited from the original [GIFEncoder](https://gist.github.com/allometry/1438842) from Laci Zsidi), minor corrections & improvements etc.* -# ================================ -# AnimGif -# ================================ +### About -AnimGif is a PHP class to create an animated GIF -- just list the source images, and that's it! +AnimGif is a PHP class to create an animated GIF -- just list the source images (in various formats), and that's it! ### Usage -**1 - Creation:** +**1. Creation:** ```php // Create an array containing file paths, resource vars (initialized with imagecreatefromXXX), @@ -37,7 +35,7 @@ $anim->create($frames, $durations); //$anim->create($frames, $durations, 5); // default: infinite looping ``` -**2 - Get the result:** +**2. Get the result:** You can now get the animated GIF binary: @@ -45,7 +43,7 @@ You can now get the animated GIF binary: $gifBinary = $anim->get(); ``` -**3 - Use it:** +**3. Use it:** Then you can send it to the browser: @@ -61,17 +59,20 @@ Or save it as a GIF file: file_put_contents('/myfolder/animated_picture.gif', $gifBinary); ``` + ### Behavior - The transparency is based on the first given frame. It will be saved only if you give multiple frames with the same transparent background. - The dimensions of the generated GIF are based on the first frame. If you need to resize your frames to get the same dimension, you can use this class: https://github.com/Sybio/ImageWorkshop. + ### Dependencies * PHP 5.3 (for namespace support) * GD (`imagecreatefromstring`, `imagegif`, `imagecolortransparent`) + ### Credits * László Zsidi: Important parts of his "GIFEncoder.class.php" have been reused. (Thanks, Laci!) From 5f5e49c9a5af8be48d690cf116b905c4619cc004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 00:58:24 +0200 Subject: [PATCH 040/120] Typo, shorter example filename --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a553c50..4020a2d 100644 --- a/README.md +++ b/README.md @@ -56,14 +56,14 @@ exit; Or save it as a GIF file: ```php -file_put_contents('/myfolder/animated_picture.gif', $gifBinary); +file_put_contents('/myfolder/animated.gif', $gifBinary); ``` ### Behavior - The transparency is based on the first given frame. It will be saved only if you give multiple frames with the same transparent background. -- The dimensions of the generated GIF are based on the first frame. If you need to resize your frames to get the same dimension, you can use +- The dimensions of the generated GIF are based on the first frame. If you need to resize your frames to get the same dimensions, you can use this class: https://github.com/Sybio/ImageWorkshop. From 250b5c6392d9acad90f0555b8b2df7ed191dc20b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 01:11:06 +0200 Subject: [PATCH 041/120] Some cleaning of the CHANGES comment --- src/GifCreator/AnimGif.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index fa4960d..4d68332 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -2,16 +2,15 @@ /* CHANGES by lunakid: TODO: -! Anim delay does not seem to be 40 ms by default... +! Default anim delay doesn't seem to be 40 ms, at all. :-o + DONE: + Fix ERR01 "Source is not a GIF image.": there's a .png in the examples! - -> And it does support non-GIF files actually. + -> And it does support non-GIF files actually! Moved the error check to resource inputs only, and changed it to "Resource is not a GIF image.". -+ The raw GIF return example is broken in the README. - (It was not caused by this code.) + create() should iterate $frames with foreach() not for assuming direct - indexes from 0 to < count. + indexes from 0 to < count. (The array keys can be anything, and should not affect the results.) + Removed unused $mode from reporting ERR02. + $duration now has a meaningful default in create(). @@ -28,7 +27,7 @@ + Moved reset() closer up to the ctor. + Changed comments here & there. + Whitespaces: fixed some tab/space mismatch etc. -+ Changed {$i} indexes to [$i] in gifBlockCompare(). (Some more left.) ++ Changed {$i} indexes to [$i] in gifBlockCompare(), just for fun. ;) */ /** From 9de7c642b8e91da9d33c08e4196dd3eced2447f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 01:14:12 +0200 Subject: [PATCH 042/120] Updated the meta stuff only, but NOT TESTED! (And as I don't use Composer, I probably won't, either. Sorry!) --- composer.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/composer.json b/composer.json index b28eddf..fc44d4f 100644 --- a/composer.json +++ b/composer.json @@ -21,8 +21,6 @@ "php": ">=5.3.0" }, "autoload": { - "psr-0": { - "GifCreator": "src", - } + "psr-0": { "GifCreator": "src" } } } From 7b82e9753e91e84df2d6b11d9c2d0187e2a68411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 02:04:54 +0200 Subject: [PATCH 043/120] Fixed delay unit mismatch (It was said to be in ms, but it's actually 1/100s.) --- src/GifCreator/AnimGif.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 4d68332..81b1dad 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -2,9 +2,12 @@ /* CHANGES by lunakid: TODO: -! Default anim delay doesn't seem to be 40 ms, at all. :-o DONE: ++ Anim delay doesn't seem to be set in ms, at all. :-o + -> Yeah, they ARE NOT in millisecs! See: http://www.w3.org/Graphics/GIF/spec-gif89a.txt + Fixing the docs. +1.1: + Fix ERR01 "Source is not a GIF image.": there's a .png in the examples! -> And it does support non-GIF files actually! Moved the error check to resource inputs only, and changed it to @@ -41,7 +44,7 @@ namespace GifCreator; -define(VERSION, '1.1'); +define(VERSION, '1.1+'); class AnimGif { @@ -100,7 +103,7 @@ public function __construct() * Create the GIF string * * @param array $frames An array of frame: can be file paths, resource image variables, binary sources or image URLs - * @param array|number $durations The duration (in ms) of each frame, or a single integer for each one. + * @param array|number $durations The duration (in 1/100s) of each frame, or a single integer for each one. * @param integer $loop Number of GIF loops before stopping animation (Set 0 to get an infinite loop) * * @return string The GIF string source From 340af3eade482bea5cb7d1269b1f4bfc771b48c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 02:08:39 +0200 Subject: [PATCH 044/120] Fixed delay time unit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4020a2d..9ef6f6c 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ $frames = array( 'http://thisisafakedomain.com/images/pic4.jpg', // URL ); -// Optionally, create an array containing the duration (in milliseconds) of each frame +// Optionally, create an array with the durations (in 1/100s units) of every frame $durations = array(40, 80, 40, 20); // Initialize and create the GIF! From 915067c870b4b0781790408e21798f2a6dfa5a5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 02:15:18 +0200 Subject: [PATCH 045/120] Fork-note updated --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 9ef6f6c..488a91e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,4 @@ -*NOTE: This is mostly a "stylistic" fork of Clément Guillemain's nice [GifCreator class](https://github.com/Sybio/GifCreator), for code cosmetics, some API changes (e.g. renaming the class), -wording fixes (partly inherited from the original [GIFEncoder](https://gist.github.com/allometry/1438842) -from Laci Zsidi), minor corrections & improvements etc.* +*(NOTE: This is mostly a "stylistic" fork of Clément Guillemain's nice [GifCreator class](https://github.com/Sybio/GifCreator), for code cosmetics, some API changes (e.g. renaming the class), several small corrections & other minor improvements scattered all over the stuff.)* ### About From a6b28038f3a71aa7d564673a74420beef3940f54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 02:25:42 +0200 Subject: [PATCH 046/120] More accurate credits --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 488a91e..c9ee328 100644 --- a/README.md +++ b/README.md @@ -73,5 +73,5 @@ this class: https://github.com/Sybio/ImageWorkshop. ### Credits -* László Zsidi: Important parts of his "GIFEncoder.class.php" have been reused. (Thanks, Laci!) +* László Zsidi: All the tough parts come from his [GIFEncoder.class.php](http://www.phpclasses.org/package/3163) (also found [here, in a Gist](https://gist.github.com/allometry/1438842).) Thanks, Laci! * Clément Guillemain: for the very handy, redesigned (& "classified") API, extensions and nice docs! From 51932484819a20812dbbc65c96aaae9980c927b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 02:26:41 +0200 Subject: [PATCH 047/120] Punctuation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c9ee328..eb376a2 100644 --- a/README.md +++ b/README.md @@ -73,5 +73,5 @@ this class: https://github.com/Sybio/ImageWorkshop. ### Credits -* László Zsidi: All the tough parts come from his [GIFEncoder.class.php](http://www.phpclasses.org/package/3163) (also found [here, in a Gist](https://gist.github.com/allometry/1438842).) Thanks, Laci! +* László Zsidi: All the tough parts come from his [GIFEncoder.class.php](http://www.phpclasses.org/package/3163) (also found [here, in a Gist](https://gist.github.com/allometry/1438842)). Thanks, Laci! * Clément Guillemain: for the very handy, redesigned (& "classified") API, extensions and nice docs! From cb97843bbf324014dfca7891679355c3e96a542c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 02:32:20 +0200 Subject: [PATCH 048/120] Fixed yet anohter leftover ms value --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index eb376a2..6e116da 100644 --- a/README.md +++ b/README.md @@ -20,13 +20,13 @@ $frames = array( ); // Optionally, create an array with the durations (in 1/100s units) of every frame -$durations = array(40, 80, 40, 20); +$durations = array(10, 30, 10, 20); // Initialize and create the GIF! $anim = new GifCreator\AnimGif(); $anim->create($frames, $durations); -// Or, for just a default even 40ms delay: +// Or, for just a default 50ms even delay: //$anim->create($frames); // Or, for 5 repeats & then stop: From 036be618fc5182e687cc326bf759d1be49430c97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 02:37:46 +0200 Subject: [PATCH 049/120] Changed default delay time to 100ms. --- src/GifCreator/AnimGif.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 81b1dad..100d732 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -4,6 +4,8 @@ TODO: DONE: ++ Oops, also need to fix the default delay. And then also change it to 100ms. + (Because browsers seem to have difficulties handling too fast animations.) + Anim delay doesn't seem to be set in ms, at all. :-o -> Yeah, they ARE NOT in millisecs! See: http://www.w3.org/Graphics/GIF/spec-gif89a.txt Fixing the docs. @@ -108,7 +110,7 @@ public function __construct() * * @return string The GIF string source */ - public function create($frames, $durations = 40, $loop = 0) + public function create($frames, $durations = 10, $loop = 0) { if (!is_array($frames)) { throw new \Exception(VERSION.': '.self::$errors['ERR00']); From 87e0e8eb975207d3ac1b8430e27907148465b4ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 02:38:34 +0200 Subject: [PATCH 050/120] Synced with the new default delay --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6e116da..337f3f0 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ $durations = array(10, 30, 10, 20); $anim = new GifCreator\AnimGif(); $anim->create($frames, $durations); -// Or, for just a default 50ms even delay: +// Or, for just a default 100ms even delay: //$anim->create($frames); // Or, for 5 repeats & then stop: From 6be1a131926c0afddc6971ca151744eb5d8af11c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 13:41:29 +0200 Subject: [PATCH 051/120] file_exists() -> @file_readable() --- src/GifCreator/AnimGif.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 100d732..3ad0c30 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -2,8 +2,13 @@ /* CHANGES by lunakid: TODO: +! BTW, unwanted PHP output: I should probably disable display_errors() in the + whole module. +! Also add check for 'allow_url_fopen' before loading from an URL. DONE: ++ file_exists() -> @file_readable() (Better to take no risk of any PHP output + in a raw GIF transfer...) + Oops, also need to fix the default delay. And then also change it to 100ms. (Because browsers seem to have difficulties handling too fast animations.) + Anim delay doesn't seem to be set in ms, at all. :-o @@ -137,7 +142,7 @@ public function create($frames, $durations = 10, $loop = 0) } elseif (is_string($frame)) { // File path or URL or Binary source code - if (file_exists($frame) || filter_var($frame, FILTER_VALIDATE_URL)) { // File path + if (@file_readable($frame) || filter_var($frame, FILTER_VALIDATE_URL)) { // File path $frame = file_get_contents($frame); } From 6c0c3beb95ed4f43023d978a936055aa0d10ffc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 13:53:32 +0200 Subject: [PATCH 052/120] Better ERR002 --- src/GifCreator/AnimGif.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 3ad0c30..8cc04d2 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -101,7 +101,7 @@ public function __construct() self::$errors = array( 'ERR00' => 'Cannot make animation from a single frame.', 'ERR01' => 'Resource is not a GIF image.', - 'ERR02' => 'You have to give image resource variables, image URLs or image binary sources in the $frames array.', + 'ERR02' => 'Only image resource variables, file paths, URLs or GD bitmaps are accepted.', 'ERR03' => 'Cannot make animation from animated GIF.', ); } From c4647b97906a5b7f7291af92d3ea6103c5e6f381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 14:03:46 +0200 Subject: [PATCH 053/120] Added error: "Loading from URLs is disabled by PHP" --- src/GifCreator/AnimGif.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 8cc04d2..857a7cd 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -4,9 +4,9 @@ TODO: ! BTW, unwanted PHP output: I should probably disable display_errors() in the whole module. -! Also add check for 'allow_url_fopen' before loading from an URL. DONE: ++ Added error + check: 'ERR04' => 'Loading from URLs is disabled by PHP.'. + file_exists() -> @file_readable() (Better to take no risk of any PHP output in a raw GIF transfer...) + Oops, also need to fix the default delay. And then also change it to 100ms. @@ -101,8 +101,9 @@ public function __construct() self::$errors = array( 'ERR00' => 'Cannot make animation from a single frame.', 'ERR01' => 'Resource is not a GIF image.', - 'ERR02' => 'Only image resource variables, file paths, URLs or GD bitmaps are accepted.', + 'ERR02' => 'Only image resource variables, file paths, URLs or bitmap binary strings are accepted.', 'ERR03' => 'Cannot make animation from animated GIF.', + 'ERR04' => 'Loading from URLs is disabled by PHP.', ); } @@ -142,8 +143,14 @@ public function create($frames, $durations = 10, $loop = 0) } elseif (is_string($frame)) { // File path or URL or Binary source code - if (@file_readable($frame) || filter_var($frame, FILTER_VALIDATE_URL)) { // File path + if (@file_readable($frame)) { // file path $frame = file_get_contents($frame); + } else if (filter_var($frame, FILTER_VALIDATE_URL)) { + if (ini_get('allow_url_fopen')) { + $frame = file_get_contents($frame); + } else { + throw new \Exception(VERSION.': '.$i.' '.self::$errors['ERR04']); + } } $resourceImg = imagecreatefromstring($frame); From c99d167661cd6aa32001ae390e6eeb65cc4a101f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 14:06:17 +0200 Subject: [PATCH 054/120] Some wording, formatting --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 337f3f0..cb7e04a 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,11 @@ AnimGif is a PHP class to create an animated GIF -- just list the source images ```php // Create an array containing file paths, resource vars (initialized with imagecreatefromXXX), -// image URLs or even binary code from image files. (All in the order as they should appear.) +// image URLs or even binary image data. (All in the order as they should appear.) $frames = array( - imagecreatefrompng("/../images/pic1.png"), // Resource var - "/../images/pic2.png", // Image file path - file_get_contents("/../images/pic3.jpg"), // Binary source code + imagecreatefrompng("/../images/pic1.png"), // resource var + "/../images/pic2.png", // image file path + file_get_contents("/../images/pic3.jpg"), // image binary data 'http://thisisafakedomain.com/images/pic4.jpg', // URL ); From 000f538a67f087000e4c4e7dac51a24d825d35cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 14:08:35 +0200 Subject: [PATCH 055/120] $gifBinary -> $gif --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cb7e04a..55a52d7 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ $anim->create($frames, $durations); You can now get the animated GIF binary: ```php -$gifBinary = $anim->get(); +$gif = $anim->get(); ``` **3. Use it:** @@ -47,14 +47,14 @@ Then you can send it to the browser: ```php header('Content-type: image/gif'); -echo $gifBinary; +echo $gif; exit; ``` Or save it as a GIF file: ```php -file_put_contents('/myfolder/animated.gif', $gifBinary); +file_put_contents('/myfolder/animated.gif', $gif); ``` From d55d069f29a6239d97924301e4fda8cdee978b93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 14:10:41 +0200 Subject: [PATCH 056/120] Wording --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 55a52d7..791c660 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ file_put_contents('/myfolder/animated.gif', $gif); ### Behavior -- The transparency is based on the first given frame. It will be saved only if you give multiple frames with the same transparent background. +- Transparency is based on the first given frame. It will be saved only if you give multiple frames with the same transparent background. - The dimensions of the generated GIF are based on the first frame. If you need to resize your frames to get the same dimensions, you can use this class: https://github.com/Sybio/ImageWorkshop. From 23a73426ae93fb6a75cc9594ddf6e6436858d465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 14:13:22 +0200 Subject: [PATCH 057/120] Changelog corrections --- src/GifCreator/AnimGif.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 857a7cd..687b391 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -15,11 +15,11 @@ -> Yeah, they ARE NOT in millisecs! See: http://www.w3.org/Graphics/GIF/spec-gif89a.txt Fixing the docs. 1.1: -+ Fix ERR01 "Source is not a GIF image.": there's a .png in the examples! ++ Fixed ERR01 "Source is not a GIF image.": there's a .png in the examples! -> And it does support non-GIF files actually! Moved the error check to resource inputs only, and changed it to "Resource is not a GIF image.". -+ create() should iterate $frames with foreach() not for assuming direct ++ create() should iterate $frames with foreach() not with for, assuming direct indexes from 0 to < count. (The array keys can be anything, and should not affect the results.) + Removed unused $mode from reporting ERR02. @@ -27,7 +27,7 @@ + $frames was incorrectly made an optional arg. of create(). + Support uniform timing without an array. + Separate ERR00 from $durations not being an array. -+ Fix leftover $GIF_tim in create(). ++ Fixed leftover $GIF_tim in create(). + Renamed method getGif() to get(). + Renamed class to AnimGif (from GifCreator). + Made $this->version a define (VERSION). From c10865aba0789925968a01e121dd6bc06e4523d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 14:15:02 +0200 Subject: [PATCH 058/120] Phrasing --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 791c660..b2718a0 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ### About -AnimGif is a PHP class to create an animated GIF -- just list the source images (in various formats), and that's it! +AnimGif is a PHP class to create an animated GIF -- just list the source images (in various forms), and that's it! ### Usage From 5db98f78e2761d745e3ae0c14db9d0dca4d878f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 14:17:47 +0200 Subject: [PATCH 059/120] Link to Sybio --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b2718a0..efbc460 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -*(NOTE: This is mostly a "stylistic" fork of Clément Guillemain's nice [GifCreator class](https://github.com/Sybio/GifCreator), for code cosmetics, some API changes (e.g. renaming the class), several small corrections & other minor improvements scattered all over the stuff.)* +*(NOTE: This is mostly a "stylistic" fork of [Clément Guillemain](https://github.com/Sybio)'s nice [GifCreator class](https://github.com/Sybio/GifCreator), for code cosmetics, some API changes (e.g. renaming the class), several small corrections & other minor improvements scattered all over the stuff.)* ### About From feee04eb544b7acc76ee74b3081e76b50e3dd0cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 14:28:36 +0200 Subject: [PATCH 060/120] Fix regression (mistyped is_readable) --- src/GifCreator/AnimGif.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 687b391..aef0f03 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -7,7 +7,7 @@ DONE: + Added error + check: 'ERR04' => 'Loading from URLs is disabled by PHP.'. -+ file_exists() -> @file_readable() (Better to take no risk of any PHP output ++ file_exists() -> @is_readable() (Better to take no risk of any PHP output in a raw GIF transfer...) + Oops, also need to fix the default delay. And then also change it to 100ms. (Because browsers seem to have difficulties handling too fast animations.) @@ -143,7 +143,7 @@ public function create($frames, $durations = 10, $loop = 0) } elseif (is_string($frame)) { // File path or URL or Binary source code - if (@file_readable($frame)) { // file path + if (@is_readable($frame)) { // file path $frame = file_get_contents($frame); } else if (filter_var($frame, FILTER_VALIDATE_URL)) { if (ini_get('allow_url_fopen')) { From 647ea74c1923a303eaa277f6a5fc86c41946e21b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 15:01:50 +0200 Subject: [PATCH 061/120] Rename encodeAsciiToChar() -> word2bin() (Since it has absolutely nothing -- thank the PHP Gods for it! -- to do with either ASCII, or chars or any other textual trans- or encoding, but pure numerical decimal to binary conversion. Phew. This will never end... ;) ) --- src/GifCreator/AnimGif.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index aef0f03..f885a4b 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -6,6 +6,7 @@ whole module. DONE: ++ Renamed encodeAsciiToChar() to word2bin(). + Added error + check: 'ERR04' => 'Loading from URLs is disabled by PHP.'. + file_exists() -> @is_readable() (Better to take no risk of any PHP output in a raw GIF transfer...) @@ -249,7 +250,7 @@ public function gifAddHeader() $this->gif .= substr($this->frameSources[0], 6, 7); $this->gif .= substr($this->frameSources[0], 13, $cmap); - $this->gif .= "!\377\13NETSCAPE2.0\3\1".encodeAsciiToChar($this->loop)."\0"; + $this->gif .= "!\377\13NETSCAPE2.0\3\1".word2bin($this->loop)."\0"; } } @@ -376,13 +377,13 @@ public function gifBlockCompare($globalBlock, $localBlock, $length) } /** - * Encode an ASCII char into a string char + * Encode an integer to 2-byte binary data * - * $param integer $char ASCII char + * @param integer $word: Number to encode * - * @return string + * @return string of 2 bytes representing @word as binary data */ -function encodeAsciiToChar($char) +function word2bin($word) { - return (chr($char & 0xFF).chr(($char >> 8) & 0xFF)); + return (chr($word & 0xFF).chr(($word >> 8) & 0xFF)); } From c4ce9d7a0589a535c22578936cc57527579999d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 15:04:23 +0200 Subject: [PATCH 062/120] Amended the changelog. --- src/GifCreator/AnimGif.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index f885a4b..c700849 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -6,7 +6,7 @@ whole module. DONE: -+ Renamed encodeAsciiToChar() to word2bin(). ++ Renamed encodeAsciiToChar() to word2bin() & fixed its description. + Added error + check: 'ERR04' => 'Loading from URLs is disabled by PHP.'. + file_exists() -> @is_readable() (Better to take no risk of any PHP output in a raw GIF transfer...) From 46018cc5836b2c0c251f710fb8692ce2a3c200a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 15:12:19 +0200 Subject: [PATCH 063/120] Mention "little-endian" at word2bin() --- src/GifCreator/AnimGif.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index c700849..827a9f4 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -377,9 +377,9 @@ public function gifBlockCompare($globalBlock, $localBlock, $length) } /** - * Encode an integer to 2-byte binary data + * Convert an integer to 2-byte little-endian binary data * - * @param integer $word: Number to encode + * @param integer $word Number to encode * * @return string of 2 bytes representing @word as binary data */ From 4fd30b0409aa3dfc05928184d0518cad90869206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 15:20:20 +0200 Subject: [PATCH 064/120] Added Matthew Flickinger's GIF page to Credits. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index efbc460..07ff7d5 100644 --- a/README.md +++ b/README.md @@ -75,3 +75,4 @@ this class: https://github.com/Sybio/ImageWorkshop. * László Zsidi: All the tough parts come from his [GIFEncoder.class.php](http://www.phpclasses.org/package/3163) (also found [here, in a Gist](https://gist.github.com/allometry/1438842)). Thanks, Laci! * Clément Guillemain: for the very handy, redesigned (& "classified") API, extensions and nice docs! +* Matthew Flickinger: for his amazing, unbeatable [GIF format dissection page](http://www.matthewflickinger.com/lab/whatsinagif/bits_and_bytes.asp). From a44b549c9645ae8539b0e45f71c00f717f3aec79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Fri, 25 Apr 2014 20:17:56 +0200 Subject: [PATCH 065/120] (Added quote bar for the taste of it.) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 07ff7d5..338e2c6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -*(NOTE: This is mostly a "stylistic" fork of [Clément Guillemain](https://github.com/Sybio)'s nice [GifCreator class](https://github.com/Sybio/GifCreator), for code cosmetics, some API changes (e.g. renaming the class), several small corrections & other minor improvements scattered all over the stuff.)* +> *NOTE: This is mostly a "stylistic" fork of [Clément Guillemain](https://github.com/Sybio)'s nice [GifCreator class](https://github.com/Sybio/GifCreator), for code cosmetics, some API changes (e.g. renaming the class), several small corrections & other minor improvements scattered all over the stuff.* ### About From 5928ce47d72fc5a836d4c4eb161ba0c93988d2bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Wed, 30 Apr 2014 16:04:16 +0200 Subject: [PATCH 066/120] Missing quotes around 'VERSION' (It's anyway still pretty lame, as defines are global (or are they local to a namespace?!), especially this VERSION name is guaranteed to clash with other crap like that...) --- src/GifCreator/AnimGif.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 827a9f4..a65aab8 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -52,7 +52,7 @@ namespace GifCreator; -define(VERSION, '1.1+'); +define('VERSION', '1.1+'); class AnimGif { From d20b91c3c441dc1fbc9bfc8e265451438c4b1d2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 11:03:27 +0200 Subject: [PATCH 067/120] Create CHANGES.txt --- CHANGES.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 CHANGES.txt diff --git a/CHANGES.txt b/CHANGES.txt new file mode 100644 index 0000000..1c1f769 --- /dev/null +++ b/CHANGES.txt @@ -0,0 +1,10 @@ +TODO: + +Add an index.php frontend for demo and quickstart (synced with the example in the +README.md). + + +------------------------------------------------------------------------------------ +DONE: + +(See the GitHub commit/release history: https://github.com/lunakid/AnimGif/commits/) From 2f9345f994464ab8b1e20932347dd77ec7ef1e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 11:18:10 +0200 Subject: [PATCH 068/120] Add more todo. --- CHANGES.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 1c1f769..fead713 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,8 +1,10 @@ TODO: -Add an index.php frontend for demo and quickstart (synced with the example in the +* Add an index.php frontend for demo and quickstart (synced with the example in the README.md). +* Allow less delay values than frames (repeating the last one). + ------------------------------------------------------------------------------------ DONE: From 986e50e509feeeee8d2771ceaf801fc54aaf91b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 11:18:59 +0200 Subject: [PATCH 069/120] Mention scandir. --- CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index fead713..e3410c4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,7 +1,7 @@ TODO: * Add an index.php frontend for demo and quickstart (synced with the example in the -README.md). +README.md), with e.g. scandir("img/") etc. * Allow less delay values than frames (repeating the last one). From 942895c2df61eee66a2b6302630e16cf4eb11e10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 11:22:05 +0200 Subject: [PATCH 070/120] Menetion file saving example & SO --- CHANGES.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index e3410c4..d87b4d4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,7 +1,8 @@ TODO: * Add an index.php frontend for demo and quickstart (synced with the example in the -README.md), with e.g. scandir("img/") etc. +README.md, AND ALSO THE ONE AT SO!), with saving a test gif file and scandir("img/") +etc. * Allow less delay values than frames (repeating the last one). From d08c910ea94a417994a9e9f6caf5bca2971f3741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 12:52:51 +0200 Subject: [PATCH 071/120] Added image load error checking. --- src/GifCreator/AnimGif.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index a65aab8..19f6df8 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -105,6 +105,7 @@ public function __construct() 'ERR02' => 'Only image resource variables, file paths, URLs or bitmap binary strings are accepted.', 'ERR03' => 'Cannot make animation from animated GIF.', 'ERR04' => 'Loading from URLs is disabled by PHP.', + 'ERR05' => 'Failed to load (or empty) image '%s'.', ); } @@ -128,7 +129,7 @@ public function create($frames, $durations = 10, $loop = 0) $i = 0; foreach ($frames as $frame) { - + $framename_maybe = $frame; // save this for reporting load errors if (is_resource($frame)) { // Resource var $resourceImg = $frame; @@ -148,11 +149,14 @@ public function create($frames, $durations = 10, $loop = 0) $frame = file_get_contents($frame); } else if (filter_var($frame, FILTER_VALIDATE_URL)) { if (ini_get('allow_url_fopen')) { - $frame = file_get_contents($frame); + $frame = @file_get_contents($frame); } else { throw new \Exception(VERSION.': '.$i.' '.self::$errors['ERR04']); } } + if (!$frame) { + throw new \Exception(VERSION.': '.$i.' '. sprintf(self::$errors['ERR05'], $framename_maybe); + } $resourceImg = imagecreatefromstring($frame); From 73f280bed25643d61cf60a92f4c40023941c8c89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 12:55:58 +0200 Subject: [PATCH 072/120] typo (syntax error) --- src/GifCreator/AnimGif.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 19f6df8..93d35d6 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -155,7 +155,7 @@ public function create($frames, $durations = 10, $loop = 0) } } if (!$frame) { - throw new \Exception(VERSION.': '.$i.' '. sprintf(self::$errors['ERR05'], $framename_maybe); + throw new \Exception(VERSION.': '.$i.' '. sprintf(self::$errors['ERR05'], $framename_maybe)); } $resourceImg = imagecreatefromstring($frame); From 4941e9477501044174d88ce8135e1ca76f9653b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 13:12:16 +0200 Subject: [PATCH 073/120] Generalized load error checking to cover format errors, too. --- src/GifCreator/AnimGif.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 93d35d6..9e943c0 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -1,9 +1,9 @@ 'Only image resource variables, file paths, URLs or bitmap binary strings are accepted.', 'ERR03' => 'Cannot make animation from animated GIF.', 'ERR04' => 'Loading from URLs is disabled by PHP.', - 'ERR05' => 'Failed to load (or empty) image '%s'.', + 'ERR05' => 'Failed to load or invalid image "%s".', ); } @@ -154,12 +154,11 @@ public function create($frames, $durations = 10, $loop = 0) throw new \Exception(VERSION.': '.$i.' '.self::$errors['ERR04']); } } - if (!$frame) { + if (! ($frame && ($resourceImg = imagecreatefromstring($frame))) ) + { throw new \Exception(VERSION.': '.$i.' '. sprintf(self::$errors['ERR05'], $framename_maybe)); } - $resourceImg = imagecreatefromstring($frame); - ob_start(); imagegif($resourceImg); $this->frameSources[] = ob_get_contents(); From 8d0dd98def8b5854a52c6d8de727140408a91a41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 13:14:28 +0200 Subject: [PATCH 074/120] Add more todo. --- CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index d87b4d4..6193ec9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -6,6 +6,9 @@ etc. * Allow less delay values than frames (repeating the last one). +* To avoid unwanted "in-band" PHP output, I should probably disable display_errors() +in the whole module (restoring it on normal exit). + ------------------------------------------------------------------------------------ DONE: From c8bb678b0f7c5fa0b650d15b5dfd49912f15f562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 13:25:02 +0200 Subject: [PATCH 075/120] Be more explicit about the nature of this fork. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 338e2c6..1862e2d 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -> *NOTE: This is mostly a "stylistic" fork of [Clément Guillemain](https://github.com/Sybio)'s nice [GifCreator class](https://github.com/Sybio/GifCreator), for code cosmetics, some API changes (e.g. renaming the class), several small corrections & other minor improvements scattered all over the stuff.* +> *NOTE: This is a fork of [Clément Guillemain](https://github.com/Sybio)'s nice [GifCreator class](https://github.com/Sybio/GifCreator), with some API changes (class rename, even more flexible parameters etc.), somewhat better error handling, several small corrections, code cosmetics & other minor improvements scattered all across.* ### About -AnimGif is a PHP class to create an animated GIF -- just list the source images (in various forms), and that's it! +AnimGif is a PHP class to create animated GIFs -- just list the source images (in various forms), and that's it! ### Usage @@ -67,7 +67,7 @@ this class: https://github.com/Sybio/ImageWorkshop. ### Dependencies -* PHP 5.3 (for namespace support) +* PHP 5.3 (for namespace support & whatnot; noone still shamelessly uses PHP < 5.3, right?!) * GD (`imagecreatefromstring`, `imagegif`, `imagecolortransparent`) From 9d446882f5ce0efe344de11ff3f755142d1226a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 13:28:10 +0200 Subject: [PATCH 076/120] Stop mixing ' and ", remove folder from file_put_contents(). --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1862e2d..dc53222 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ $frames = array( imagecreatefrompng("/../images/pic1.png"), // resource var "/../images/pic2.png", // image file path file_get_contents("/../images/pic3.jpg"), // image binary data - 'http://thisisafakedomain.com/images/pic4.jpg', // URL + "http://thisisafakedomain.com/images/pic4.jpg", // URL ); // Optionally, create an array with the durations (in 1/100s units) of every frame @@ -46,7 +46,7 @@ $gif = $anim->get(); Then you can send it to the browser: ```php -header('Content-type: image/gif'); +header("Content-type: image/gif"); echo $gif; exit; ``` @@ -54,7 +54,7 @@ exit; Or save it as a GIF file: ```php -file_put_contents('/myfolder/animated.gif', $gif); +file_put_contents("animated.gif", $gif); ``` From bdf6557786f869ad8ba7c4a4ded0a8c3439c2336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 15:31:51 +0200 Subject: [PATCH 077/120] Rephrase ERR02. --- src/GifCreator/AnimGif.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 9e943c0..c53f052 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -102,7 +102,7 @@ public function __construct() self::$errors = array( 'ERR00' => 'Cannot make animation from a single frame.', 'ERR01' => 'Resource is not a GIF image.', - 'ERR02' => 'Only image resource variables, file paths, URLs or bitmap binary strings are accepted.', + 'ERR02' => 'Only image resource variables, file paths, URLs or binary bitmap data are accepted.', 'ERR03' => 'Cannot make animation from animated GIF.', 'ERR04' => 'Loading from URLs is disabled by PHP.', 'ERR05' => 'Failed to load or invalid image "%s".', From 0aacf22bfc159d18effc2354462636475add76f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 15:35:11 +0200 Subject: [PATCH 078/120] Preserve frame name + slightly clearer flow for non-resources in clear(). --- src/GifCreator/AnimGif.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index c53f052..bac4089 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -129,7 +129,6 @@ public function create($frames, $durations = 10, $loop = 0) $i = 0; foreach ($frames as $frame) { - $framename_maybe = $frame; // save this for reporting load errors if (is_resource($frame)) { // Resource var $resourceImg = $frame; @@ -146,17 +145,21 @@ public function create($frames, $durations = 10, $loop = 0) } elseif (is_string($frame)) { // File path or URL or Binary source code if (@is_readable($frame)) { // file path - $frame = file_get_contents($frame); + $bin = file_get_contents($frame); } else if (filter_var($frame, FILTER_VALIDATE_URL)) { if (ini_get('allow_url_fopen')) { - $frame = @file_get_contents($frame); + $bin = @file_get_contents($frame); } else { throw new \Exception(VERSION.': '.$i.' '.self::$errors['ERR04']); } + } else { + $bin = $frame; } - if (! ($frame && ($resourceImg = imagecreatefromstring($frame))) ) + + if (! ($bin && ($resourceImg = imagecreatefromstring($frame))) ) { - throw new \Exception(VERSION.': '.$i.' '. sprintf(self::$errors['ERR05'], $framename_maybe)); + throw new \Exception(VERSION.': '.$i.' ' + . sprintf(self::$errors['ERR05'], substr($frame, 0, 200))); //!! $frame may be binary data, not a name! } ob_start(); From 4fd80eb5a83e20d288c2b7884b18b0bac4c3521f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 15:38:24 +0200 Subject: [PATCH 079/120] Preserve frame name + slightly clearer flow for non-resources in create(). (There was an error in the previous commit: both in the code and in the commit message...) --- src/GifCreator/AnimGif.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index bac4089..e192872 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -156,7 +156,7 @@ public function create($frames, $durations = 10, $loop = 0) $bin = $frame; } - if (! ($bin && ($resourceImg = imagecreatefromstring($frame))) ) + if (! ($bin && ($resourceImg = imagecreatefromstring($bin))) ) { throw new \Exception(VERSION.': '.$i.' ' . sprintf(self::$errors['ERR05'], substr($frame, 0, 200))); //!! $frame may be binary data, not a name! From 953e0a2599025e8a54cf16454eaadbfca036e257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 15:56:03 +0200 Subject: [PATCH 080/120] Transparent-color-handling code normalized. --- src/GifCreator/AnimGif.php | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index e192872..410583b 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -82,9 +82,9 @@ class AnimGif private $dis; /** - * @var integer Gif color + * @var integer Gif transparent color index */ - private $colour; + private $transparent_color; /** * @var array @@ -172,7 +172,7 @@ public function create($frames, $durations = 10, $loop = 0) } if ($i == 0) { - $colour = imagecolortransparent($resourceImg); + $this->transparent_color = imagecolortransparent($resourceImg); } for ($j = (13 + 3 * (2 << (ord($this->frameSources[$i] { 10 }) & 0x07))), $k = TRUE; $k; $j++) { @@ -198,12 +198,6 @@ public function create($frames, $durations = 10, $loop = 0) ++$i; }//foreach - if (isset($colour)) { - $this->colour = $colour; - } else { - $red = $green = $blue = 0; - $this->colour = ($red > -1 && $green > -1 && $blue > -1) ? ($red | ($green << 8) | ($blue << 16)) : -1; - } $this->gifAddHeader(); @@ -240,7 +234,7 @@ public function reset() $this->imgBuilt = false; $this->loop = 0; $this->dis = 2; - $this->colour = -1; + $this->transparent_colorc = -1; } /** @@ -281,13 +275,13 @@ public function addGifFrames($i, $d) $Locals_ext = "!\xF9\x04".chr(($this->dis << 2) + 0).chr(($d >> 0 ) & 0xFF).chr(($d >> 8) & 0xFF)."\x0\x0"; - if ($this->colour > -1 && ord($this->frameSources[$i] { 10 }) & 0x80) { + if ($this->transparent_color > -1 && ord($this->frameSources[$i] { 10 }) & 0x80) { for ($j = 0; $j < (2 << (ord($this->frameSources[$i] { 10 } ) & 0x07)); $j++) { - if (ord($Locals_rgb { 3 * $j + 0 }) == (($this->colour >> 16) & 0xFF) && - ord($Locals_rgb { 3 * $j + 1 }) == (($this->colour >> 8) & 0xFF) && - ord($Locals_rgb { 3 * $j + 2 }) == (($this->colour >> 0) & 0xFF) + if (ord($Locals_rgb { 3 * $j + 0 }) == (($this->transparent_color >> 16) & 0xFF) && + ord($Locals_rgb { 3 * $j + 1 }) == (($this->transparent_color >> 8) & 0xFF) && + ord($Locals_rgb { 3 * $j + 2 }) == (($this->transparent_color >> 0) & 0xFF) ) { $Locals_ext = "!\xF9\x04".chr(($this->dis << 2) + 1).chr(($d >> 0) & 0xFF).chr(($d >> 8) & 0xFF).chr($j)."\x0"; break; From 65cfb15cb863b3bd56627ace76f949e36caaddce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 16:03:22 +0200 Subject: [PATCH 081/120] Use previous delay by default. Also use word2bin($delay) in addGifFrames($i, $delay). --- src/GifCreator/AnimGif.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 410583b..75de5ec 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -56,6 +56,8 @@ class AnimGif { + const DEFAULT_DURATION = 10; + /** * @var string The generated (binary) image */ @@ -118,8 +120,10 @@ public function __construct() * * @return string The GIF string source */ - public function create($frames, $durations = 10, $loop = 0) + public function create($frames, $durations = self::DEFAULT_DURATION, $loop = 0) { + $last_duration = self::DEFAULT_DURATION; // used only if $durations is an array + if (!is_array($frames)) { throw new \Exception(VERSION.': '.self::$errors['ERR00']); } @@ -203,7 +207,15 @@ public function create($frames, $durations = 10, $loop = 0) for ($i = 0; $i < count($this->frameSources); $i++) { - $this->addGifFrames($i, is_array($durations) ? $durations[$i] : $durations); + // Use the last delay, if none has been specified for the current frame + if (is_array($durations)) { + $d = (empty($durations[$i]) ? $last_duration : $durations[$i]); + $last_duration = $d; + } else { + $d = $durations; + } + + $this->addGifFrames($i, $d); } $this->gifAddFooter(); @@ -273,7 +285,7 @@ public function addGifFrames($i, $d) $Global_rgb = substr($this->frameSources[ 0], 13, 3 * (2 << (ord($this->frameSources[ 0] { 10 }) & 0x07))); $Locals_rgb = substr($this->frameSources[$i], 13, 3 * (2 << (ord($this->frameSources[$i] { 10 }) & 0x07))); - $Locals_ext = "!\xF9\x04".chr(($this->dis << 2) + 0).chr(($d >> 0 ) & 0xFF).chr(($d >> 8) & 0xFF)."\x0\x0"; + $Locals_ext = "!\xF9\x04" . chr(($this->dis << 2) + 0) . word2bin($d) . "\x0\x0"; if ($this->transparent_color > -1 && ord($this->frameSources[$i] { 10 }) & 0x80) { From 47d3575062f4b17692776ad220a68e2917af58b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 16:59:00 +0200 Subject: [PATCH 082/120] Pointers to external (no longer in-file) change docs. --- src/GifCreator/AnimGif.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 75de5ec..135909c 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -2,10 +2,12 @@ /* CHANGES of the "lunakid fork": -TODO: -! See CHANGES.txt. +See CHANGES.txt for TODO items and release notes! DONE: ++ See the GitHub commit log for a detailed change history! +-------- +Old manual change log (parlty parallel with the GitHub commit log): + Renamed encodeAsciiToChar() to word2bin() & fixed its description. + Added error + check: 'ERR04' => 'Loading from URLs is disabled by PHP.'. + file_exists() -> @is_readable() (Better to take no risk of any PHP output From 42cf67bc460acfc7487eadfcfae88f5fbe77f3b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 17:07:02 +0200 Subject: [PATCH 083/120] Refer to GitHub releases and commits. --- CHANGES.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 6193ec9..449c812 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,8 +4,6 @@ TODO: README.md, AND ALSO THE ONE AT SO!), with saving a test gif file and scandir("img/") etc. -* Allow less delay values than frames (repeating the last one). - * To avoid unwanted "in-band" PHP output, I should probably disable display_errors() in the whole module (restoring it on normal exit). @@ -13,4 +11,5 @@ in the whole module (restoring it on normal exit). ------------------------------------------------------------------------------------ DONE: -(See the GitHub commit/release history: https://github.com/lunakid/AnimGif/commits/) +-> Release notes: https://github.com/lunakid/AnimGif/releases/ +-> See also the GitHub commit history: https://github.com/lunakid/AnimGif/commits/ From d21dda965546a3c0e99d991583485f5e0b188739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 17:08:21 +0200 Subject: [PATCH 084/120] Error handling improved. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dc53222..359ce6b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -> *NOTE: This is a fork of [Clément Guillemain](https://github.com/Sybio)'s nice [GifCreator class](https://github.com/Sybio/GifCreator), with some API changes (class rename, even more flexible parameters etc.), somewhat better error handling, several small corrections, code cosmetics & other minor improvements scattered all across.* +> *NOTE: This is a fork of [Clément Guillemain](https://github.com/Sybio)'s nice [GifCreator class](https://github.com/Sybio/GifCreator), with some API changes (class rename, even more flexible parameters etc.), better error handling, several small corrections, code cosmetics & other minor improvements scattered all across.* ### About From bfe48b5a463203d73c23e4c8956a81620d022178 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 17:10:28 +0200 Subject: [PATCH 085/120] Phrasing... --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 359ce6b..06a0881 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -> *NOTE: This is a fork of [Clément Guillemain](https://github.com/Sybio)'s nice [GifCreator class](https://github.com/Sybio/GifCreator), with some API changes (class rename, even more flexible parameters etc.), better error handling, several small corrections, code cosmetics & other minor improvements scattered all across.* +> *NOTE: This is a fork of [Clément Guillemain](https://github.com/Sybio)'s nice [GifCreator class](https://github.com/Sybio/GifCreator), with some API changes (class & some methods renamed, more flexible parameters etc.), better error handling, several small corrections, code cosmetics & other minor improvements scattered all across.* ### About From 276802cbbfa37086db6e7ab0540d3cfc4e8dd8a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 17:18:15 +0200 Subject: [PATCH 086/120] Add the multi-delay bug. --- CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 449c812..268469f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,8 @@ TODO: +* In local testing I had a strange issue with by-frame delays: the first image eats +up the first two delays, and is shown for the sum of those two numbers... :-o + * Add an index.php frontend for demo and quickstart (synced with the example in the README.md, AND ALSO THE ONE AT SO!), with saving a test gif file and scandir("img/") etc. From 6ca5608f9772a0cbd67d8d76ba5b236155f0a4c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 18:15:50 +0200 Subject: [PATCH 087/120] VERSION: define() -> const (namespaced!) I already had - and then reverted this change once, but forgot why... --- src/GifCreator/AnimGif.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 135909c..4db9599 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -54,7 +54,7 @@ namespace GifCreator; -define('VERSION', '1.1+'); +const 'VERSION' = '1.2-pre+'; // "rolling pre-release"... class AnimGif { From c218961fae3c23791ed67b16ea3988e58df7637b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 18:38:09 +0200 Subject: [PATCH 088/120] Fix: 'VERSION' -> VERSION --- src/GifCreator/AnimGif.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 4db9599..c0aff49 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -54,7 +54,7 @@ namespace GifCreator; -const 'VERSION' = '1.2-pre+'; // "rolling pre-release"... +const VERSION = '1.2-pre+'; // "rolling pre-release"... class AnimGif { From a74c2e9d18f4edb5412ffbc29b69668a97a82f54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 18:39:58 +0200 Subject: [PATCH 089/120] Typo --- src/GifCreator/AnimGif.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index c0aff49..7f42141 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -7,7 +7,7 @@ DONE: + See the GitHub commit log for a detailed change history! -------- -Old manual change log (parlty parallel with the GitHub commit log): +Old (pre-1.2) manual change log (partly parallel with the GitHub commit log): + Renamed encodeAsciiToChar() to word2bin() & fixed its description. + Added error + check: 'ERR04' => 'Loading from URLs is disabled by PHP.'. + file_exists() -> @is_readable() (Better to take no risk of any PHP output From ac25ba274953b6ae04faa99098b58ecb51797e40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 18:41:26 +0200 Subject: [PATCH 090/120] Reprod. details for the delay bug. --- CHANGES.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 268469f..9a2c415 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,14 +1,15 @@ TODO: * In local testing I had a strange issue with by-frame delays: the first image eats -up the first two delays, and is shown for the sum of those two numbers... :-o + up the first two delays, and is shown for the sum of those two numbers... :-o + -> And I seem to be unable to reproduce it now! :-o * Add an index.php frontend for demo and quickstart (synced with the example in the -README.md, AND ALSO THE ONE AT SO!), with saving a test gif file and scandir("img/") -etc. + README.md, AND ALSO THE ONE AT SO!), with saving a test gif file and scandir("img/") + etc. * To avoid unwanted "in-band" PHP output, I should probably disable display_errors() -in the whole module (restoring it on normal exit). + in the whole module (restoring it on normal exit). ------------------------------------------------------------------------------------ From 8496704c7e86bd537152e5588a87151eb07b8076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 19:09:20 +0200 Subject: [PATCH 091/120] Fix version nr. --- src/GifCreator/AnimGif.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 7f42141..f1ab7ac 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -54,7 +54,7 @@ namespace GifCreator; -const VERSION = '1.2-pre+'; // "rolling pre-release"... +const VERSION = '1.2'; class AnimGif { From 15acbe73586df3363cbb55e43e8ce78854714a9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 19:12:06 +0200 Subject: [PATCH 092/120] More todo. --- CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 9a2c415..df16f2c 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,6 +4,9 @@ TODO: up the first two delays, and is shown for the sum of those two numbers... :-o -> And I seem to be unable to reproduce it now! :-o +* Accept a local dir for the image list. (Do - & warn about - explicit sorting if + per-frame delays are specified.) + * Add an index.php frontend for demo and quickstart (synced with the example in the README.md, AND ALSO THE ONE AT SO!), with saving a test gif file and scandir("img/") etc. From cfc97251118c2e9c452c34fb9056b59461533a99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 19:13:52 +0200 Subject: [PATCH 093/120] More todo. --- CHANGES.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index df16f2c..a210f1f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,8 @@ TODO: -* In local testing I had a strange issue with by-frame delays: the first image eats +* Do file_put_contents($name) for API call $->gif($name). + +! In local testing I had a strange issue with by-frame delays: the first image eats up the first two delays, and is shown for the sum of those two numbers... :-o -> And I seem to be unable to reproduce it now! :-o From 70998d7d7b3535d2e6148738ba6c7f3b21455ac5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 19:15:19 +0200 Subject: [PATCH 094/120] Fixed todo for save(). --- CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index a210f1f..13f378c 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,6 @@ TODO: -* Do file_put_contents($name) for API call $->gif($name). +* Add API call $->save($name) in addition to get(). ! In local testing I had a strange issue with by-frame delays: the first image eats up the first two delays, and is shown for the sum of those two numbers... :-o From 92ed512fafb927f8409b49c0f077f1bde02939bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 19:19:07 +0200 Subject: [PATCH 095/120] Added API call $->save($filename) --- src/GifCreator/AnimGif.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index f1ab7ac..ee146bf 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -226,7 +226,7 @@ public function create($frames, $durations = self::DEFAULT_DURATION, $loop = 0) } /** - * Get the final GIF image string + * Get the resulting GIF image binary * * @return string */ @@ -235,6 +235,18 @@ public function get() return $this->gif; } + /** + * Save the resulting GIF to a file. + * + * @param $filename String Target file path + * + * @return that of file_put_contents($filename) + */ + public function save($filename) + { + return file_put_contents($filename, $this->gif); + } + // Internals // =================================================================================== From d7312b30d7711adf049c131d8578887e4b200c81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 19:19:45 +0200 Subject: [PATCH 096/120] Move $->save($name) to release notes. --- CHANGES.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 13f378c..82d73f5 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,7 +1,5 @@ TODO: -* Add API call $->save($name) in addition to get(). - ! In local testing I had a strange issue with by-frame delays: the first image eats up the first two delays, and is shown for the sum of those two numbers... :-o -> And I seem to be unable to reproduce it now! :-o From d9783591c8785bcd49a8f8c71edc6072bedeb699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 17 May 2014 19:21:46 +0200 Subject: [PATCH 097/120] Version bumped to 1.3-pre+ ("rolling pre-release") --- src/GifCreator/AnimGif.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index ee146bf..2aaac7d 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -54,7 +54,7 @@ namespace GifCreator; -const VERSION = '1.2'; +const VERSION = '1.3-pre+'; // "rolling pre-release"... ;) class AnimGif { From fdcb5bb7989e1ac93633e41c66b1591f5dba8e92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 24 May 2014 00:08:57 +0200 Subject: [PATCH 098/120] Make reset() public & fix 2 typos in it. (Actually, reset() was public already; made the internals protected, in fact.) --- src/GifCreator/AnimGif.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 2aaac7d..d00fbb6 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -247,26 +247,26 @@ public function save($filename) return file_put_contents($filename, $this->gif); } - // Internals - // =================================================================================== - /** - * Reset and clean the current object (only used by the ctor. currently) + * Clean-up the current object (also used by the ctor.) */ public function reset() { - $this->frameSources; + $this->frameSources = null; $this->gif = 'GIF89a'; // the GIF header $this->imgBuilt = false; $this->loop = 0; $this->dis = 2; - $this->transparent_colorc = -1; + $this->transparent_color = -1; } + // Internals + // =================================================================================== + /** * Add the header gif string in its source */ - public function gifAddHeader() + protected function gifAddHeader() { $cmap = 0; @@ -286,7 +286,7 @@ public function gifAddHeader() * @param integer $i * @param integer $d */ - public function addGifFrames($i, $d) + protected function addGifFrames($i, $d) { $Locals_str = 13 + 3 * (2 << (ord($this->frameSources[ $i ] { 10 }) & 0x07)); @@ -371,7 +371,7 @@ public function addGifFrames($i, $d) /** * Add the gif string footer char */ - public function gifAddFooter() + protected function gifAddFooter() { $this->gif .= ';'; } @@ -385,7 +385,7 @@ public function gifAddFooter() * * @return integer */ - public function gifBlockCompare($globalBlock, $localBlock, $length) + protected function gifBlockCompare($globalBlock, $localBlock, $length) { for ($i = 0; $i < $length; $i++) { From c346a768666b71cdee1cb3749d2547c3deeceb8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 24 May 2014 01:07:28 +0200 Subject: [PATCH 099/120] Added image dir source. Also: improved comments and error messages. --- src/GifCreator/AnimGif.php | 48 +++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index d00fbb6..8285b6e 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -102,40 +102,62 @@ public function __construct() { $this->reset(); - // Static data self::$errors = array( - 'ERR00' => 'Cannot make animation from a single frame.', + 'ERR00' => 'Need at least 2 frames for an animation.', 'ERR01' => 'Resource is not a GIF image.', 'ERR02' => 'Only image resource variables, file paths, URLs or binary bitmap data are accepted.', 'ERR03' => 'Cannot make animation from animated GIF.', 'ERR04' => 'Loading from URLs is disabled by PHP.', - 'ERR05' => 'Failed to load or invalid image "%s".', + 'ERR05' => 'Failed to load or invalid image (dir): "%s".', ); } /** - * Create the GIF string + * Create animated GIF from source images * - * @param array $frames An array of frame: can be file paths, resource image variables, binary sources or image URLs - * @param array|number $durations The duration (in 1/100s) of each frame, or a single integer for each one. - * @param integer $loop Number of GIF loops before stopping animation (Set 0 to get an infinite loop) + * @param array $frames The source iamges: can be a local dir path, or an array + * of file paths, resource image variables, binary data or image URLs. + * @param array|number $durations The duration (in 1/100s) of the individual frames, + * or a single integer for each one. + * @param integer $loop Number of loops before stopping the animation (set to 0 for an infinite loop). * - * @return string The GIF string source + * @return string The resulting GIF binary data. */ public function create($frames, $durations = self::DEFAULT_DURATION, $loop = 0) { $last_duration = self::DEFAULT_DURATION; // used only if $durations is an array + $this->loop = ($loop > -1) ? $loop : 0; + $this->dis = 2; + + // Check if $frames is a dir; get all files in ascending order if yes (else die): if (!is_array($frames)) { - throw new \Exception(VERSION.': '.self::$errors['ERR00']); + $frames_dir = $frames; + if (@is_dir($frames_dir)) { + if ($frames = scandir($frames_dir)) { + $frames = array_filter($frames, function($x) { return $x != "." && $x != ".."; }); + + array_walk($frames, function(&$x, $i) use ($frames_dir) { + $x = "$frames_dir/$x"; }); + + } + } + + if (!is_array($frames)) { + throw new \Exception(VERSION.': ' + . sprintf(self::$errors['ERR05'], $frames_dir)); // $frame is expected to be a string here; see the other ERR05 case! + } } - $this->loop = ($loop > -1) ? $loop : 0; - $this->dis = 2; + assert(is_array($frames)); + + if (sizeof($frames) < 2) { + throw new \Exception(VERSION.': '.self::$errors['ERR00']); + } $i = 0; foreach ($frames as $frame) { - if (is_resource($frame)) { // Resource var + if (is_resource($frame)) { // in-memory image resource (hopefully) $resourceImg = $frame; @@ -148,7 +170,7 @@ public function create($frames, $durations = self::DEFAULT_DURATION, $loop = 0) throw new \Exception(VERSION.': '.$i.' '.self::$errors['ERR01']); } - } elseif (is_string($frame)) { // File path or URL or Binary source code + } elseif (is_string($frame)) { // file path, URL or binary data if (@is_readable($frame)) { // file path $bin = file_get_contents($frame); From 5fdc0350b99c58d78222046968cafb7f2d74a519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 24 May 2014 01:13:43 +0200 Subject: [PATCH 100/120] Version to 1.3 & fix return from create(). --- src/GifCreator/AnimGif.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 8285b6e..e7c69f8 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -54,7 +54,7 @@ namespace GifCreator; -const VERSION = '1.3-pre+'; // "rolling pre-release"... ;) +const VERSION = '1.3'; class AnimGif { @@ -244,7 +244,7 @@ public function create($frames, $durations = self::DEFAULT_DURATION, $loop = 0) $this->gifAddFooter(); - return $this->gif; + return $this; } /** From 9a260b9b97d586e5205c3d931585bcce29298534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 24 May 2014 01:21:14 +0200 Subject: [PATCH 101/120] Add slideshow example for convenience. --- index.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 index.php diff --git a/index.php b/index.php new file mode 100644 index 0000000..4d153ff --- /dev/null +++ b/index.php @@ -0,0 +1,15 @@ + create("img", array(300, 500)) // first 3s, then 5s for all the others + -> save("anim.gif"); + +?> From 090e2f8fdd22a2cf3de3c8cf14d894ef976330b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 24 May 2014 01:25:27 +0200 Subject: [PATCH 102/120] Removed stuff already in the new release notes. --- CHANGES.txt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 82d73f5..ea1de73 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,15 +4,13 @@ TODO: up the first two delays, and is shown for the sum of those two numbers... :-o -> And I seem to be unable to reproduce it now! :-o -* Accept a local dir for the image list. (Do - & warn about - explicit sorting if - per-frame delays are specified.) +* Warn about explicit sorting if per-frame delays are specified for a dir source? -* Add an index.php frontend for demo and quickstart (synced with the example in the - README.md, AND ALSO THE ONE AT SO!), with saving a test gif file and scandir("img/") - etc. +* Sync the index.php (demo & quickstart frontend) with the examples in README.md + AND ALSO THE ONE AT SO! * To avoid unwanted "in-band" PHP output, I should probably disable display_errors() - in the whole module (restoring it on normal exit). + in the whole module (restoring it on normal exit)... ------------------------------------------------------------------------------------ From ffe03968556a96c8b12818577c3d8a3f6ea7a0ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 24 May 2014 01:38:38 +0200 Subject: [PATCH 103/120] Synced & combed for 1.3. --- README.md | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 06a0881..8f592a0 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,8 @@ AnimGif is a PHP class to create animated GIFs -- just list the source images (i **1. Creation:** ```php -// Create an array containing file paths, resource vars (initialized with imagecreatefromXXX), -// image URLs or even binary image data. (All in the order as they should appear.) +// Use an array containing file paths, resource vars (initialized with imagecreatefromXXX), +// image URLs or binary image data. $frames = array( imagecreatefrompng("/../images/pic1.png"), // resource var "/../images/pic2.png", // image file path @@ -19,14 +19,20 @@ $frames = array( "http://thisisafakedomain.com/images/pic4.jpg", // URL ); -// Optionally, create an array with the durations (in 1/100s units) of every frame -$durations = array(10, 30, 10, 20); +// Or, load the image files from a dir (and sort them): +//$frames = "../images"; + +// Optionally, set the duration (in 1/100s units) for each frame +$durations = array(20, 30, 10, 10); + +// Or, with the shorthand form (omitting the repetitions): +$durations = array(20, 30, 10); // Initialize and create the GIF! $anim = new GifCreator\AnimGif(); $anim->create($frames, $durations); -// Or, for just a default 100ms even delay: +// Or, for just use a default 100ms even delay: //$anim->create($frames); // Or, for 5 repeats & then stop: @@ -43,7 +49,7 @@ $gif = $anim->get(); **3. Use it:** -Then you can send it to the browser: +Then you might send it directly to the browser: ```php header("Content-type: image/gif"); @@ -51,7 +57,7 @@ echo $gif; exit; ``` -Or save it as a GIF file: +Or save it to a file: ```php file_put_contents("animated.gif", $gif); @@ -60,9 +66,8 @@ file_put_contents("animated.gif", $gif); ### Behavior -- Transparency is based on the first given frame. It will be saved only if you give multiple frames with the same transparent background. -- The dimensions of the generated GIF are based on the first frame. If you need to resize your frames to get the same dimensions, you can use -this class: https://github.com/Sybio/ImageWorkshop. +- Transparency is based on the first frame. [!!NOT VERIFIED: "It will be saved only if you give multiple frames with the same transparent background"] +- The dimensions of the generated GIF are based on the first frame, too. If you need to resize your images to get the same dimensions, you can use this class: https://github.com/Sybio/ImageWorkshop. ### Dependencies From 36bceba197ce1c7ce80902a569a2070d01839cb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 24 May 2014 01:44:38 +0200 Subject: [PATCH 104/120] Example for selective omission of delays. --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8f592a0..5ede739 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,10 @@ $frames = array( $durations = array(20, 30, 10, 10); // Or, with the shorthand form (omitting the repetitions): -$durations = array(20, 30, 10); +//$durations = array(20, 30, 10); +// Or, even: +$durations = array(250, null, null, 500); + // Initialize and create the GIF! $anim = new GifCreator\AnimGif(); From 7864cc48cbcf73494a7bbf6d90abe4ba3eac5e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 24 May 2014 01:45:11 +0200 Subject: [PATCH 105/120] Add a missing // --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5ede739..c60001d 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ $durations = array(20, 30, 10, 10); // Or, with the shorthand form (omitting the repetitions): //$durations = array(20, 30, 10); // Or, even: -$durations = array(250, null, null, 500); +//$durations = array(250, null, null, 500); // Initialize and create the GIF! From 73b476c216bda93e0451e15c5a316232fd487bcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 24 May 2014 01:47:26 +0200 Subject: [PATCH 106/120] Mention new methods --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c60001d..c10b462 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -> *NOTE: This is a fork of [Clément Guillemain](https://github.com/Sybio)'s nice [GifCreator class](https://github.com/Sybio/GifCreator), with some API changes (class & some methods renamed, more flexible parameters etc.), better error handling, several small corrections, code cosmetics & other minor improvements scattered all across.* +> *NOTE: This is a fork of [Clément Guillemain](https://github.com/Sybio)'s nice [GifCreator class](https://github.com/Sybio/GifCreator), with some API changes (class & some methods renamed, some added, more flexible (and robust) parameter handling etc.), better error handling, several small corrections, code cosmetics & other minor improvements scattered all across.* ### About From 71f5f98676a33af5108393e9824477ce7cdf59e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 24 May 2014 01:50:05 +0200 Subject: [PATCH 107/120] Change old file_put_contents() to $->save() --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c10b462..585e8fa 100644 --- a/README.md +++ b/README.md @@ -60,10 +60,10 @@ echo $gif; exit; ``` -Or save it to a file: +Or just save it to a file: ```php -file_put_contents("animated.gif", $gif); +$anim->save("animated.gif"); ``` From 449aa6f7e5c4cdf236fb1b7b29019c77442153c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 24 May 2014 01:51:27 +0200 Subject: [PATCH 108/120] Streamlined the usage part a bit. --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 585e8fa..0fb4057 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ $anim->create($frames, $durations); //$anim->create($frames, $durations, 5); // default: infinite looping ``` -**2. Get the result:** +**2. Get/use the result:** You can now get the animated GIF binary: @@ -50,9 +50,7 @@ You can now get the animated GIF binary: $gif = $anim->get(); ``` -**3. Use it:** - -Then you might send it directly to the browser: +...and e.g. send it directly to the browser: ```php header("Content-type: image/gif"); From b71d3f8326cbe3eec93746675014867d50b5595b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 24 May 2014 01:52:23 +0200 Subject: [PATCH 109/120] Minor clarification --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0fb4057..b8e4d06 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ AnimGif is a PHP class to create animated GIFs -- just list the source images (i ### Usage -**1. Creation:** +**1. Creation/setup:** ```php // Use an array containing file paths, resource vars (initialized with imagecreatefromXXX), From ca70ed671f806ef0e95ea128b5da6eacb06d1d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 31 May 2014 09:43:02 +0200 Subject: [PATCH 110/120] Rename index.php to test/index.php --- index.php => test/index.php | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename index.php => test/index.php (100%) diff --git a/index.php b/test/index.php similarity index 100% rename from index.php rename to test/index.php From aa66a57e74e29e70ebad2c226797356c494feeeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 31 May 2014 09:43:47 +0200 Subject: [PATCH 111/120] Moved test stuff to test/. --- test/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/index.php b/test/index.php index 4d153ff..94b119f 100644 --- a/test/index.php +++ b/test/index.php @@ -1,7 +1,7 @@ create("img", array(300, 500)) // first 3s, then 5s for all the others +$anim -> create("img/", array(300, 500)) // first 3s, then 5s for all the others -> save("anim.gif"); ?> From 2fb80d5e9cec06797a9eab0d228a7d7b1d0cd24c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 31 May 2014 09:44:50 +0200 Subject: [PATCH 112/120] Image dir added --- test/img/.KEEP | 1 + 1 file changed, 1 insertion(+) create mode 100644 test/img/.KEEP diff --git a/test/img/.KEEP b/test/img/.KEEP new file mode 100644 index 0000000..dcc0fc2 --- /dev/null +++ b/test/img/.KEEP @@ -0,0 +1 @@ +DIR PIN From 3970dea783e6c5f617220d6f2e389aed89244f5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 31 May 2014 10:15:06 +0200 Subject: [PATCH 113/120] Skip .files in image dirs (for now). (I didn't want to force this, but to keep GIT shut up over the empty test dir, I have a .KEEP file there, so...) --- src/GifCreator/AnimGif.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index e7c69f8..029c6c9 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -54,7 +54,7 @@ namespace GifCreator; -const VERSION = '1.3'; +const VERSION = '1.3+'; class AnimGif { @@ -135,11 +135,13 @@ public function create($frames, $durations = self::DEFAULT_DURATION, $loop = 0) $frames_dir = $frames; if (@is_dir($frames_dir)) { if ($frames = scandir($frames_dir)) { - $frames = array_filter($frames, function($x) { return $x != "." && $x != ".."; }); + $frames = array_filter($frames, function($x) { + // Should these two below be selectable? + return $x[0] != "."; // Or: $x != "." && $x != ".."; + }); array_walk($frames, function(&$x, $i) use ($frames_dir) { $x = "$frames_dir/$x"; }); - } } From d63101016e0fd0980f6615ddceb583f64a0e2668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 31 May 2014 10:24:09 +0200 Subject: [PATCH 114/120] Restructure the example section a bit --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b8e4d06..f6c2fc6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -> *NOTE: This is a fork of [Clément Guillemain](https://github.com/Sybio)'s nice [GifCreator class](https://github.com/Sybio/GifCreator), with some API changes (class & some methods renamed, some added, more flexible (and robust) parameter handling etc.), better error handling, several small corrections, code cosmetics & other minor improvements scattered all across.* +> *NOTE: This is a fork of [Clément Guillemain](https://github.com/Sybio)'s nice [GifCreator class](https://github.com/Sybio/GifCreator), with some API changes (class rename, new & updated methods, more flexible (and robust) parameter handling etc.), better error handling, several small corrections, code cosmetics & other improvements scattered all across.* ### About @@ -7,7 +7,7 @@ AnimGif is a PHP class to create animated GIFs -- just list the source images (i ### Usage -**1. Creation/setup:** +**1. Inputs:** ```php // Use an array containing file paths, resource vars (initialized with imagecreatefromXXX), @@ -19,7 +19,7 @@ $frames = array( "http://thisisafakedomain.com/images/pic4.jpg", // URL ); -// Or, load the image files from a dir (and sort them): +// Or, load the image files from a dir (sorted): //$frames = "../images"; // Optionally, set the duration (in 1/100s units) for each frame @@ -29,8 +29,11 @@ $durations = array(20, 30, 10, 10); //$durations = array(20, 30, 10); // Or, even: //$durations = array(250, null, null, 500); +``` +**2. Create the GIF:** +``` php // Initialize and create the GIF! $anim = new GifCreator\AnimGif(); $anim->create($frames, $durations); @@ -42,7 +45,7 @@ $anim->create($frames, $durations); //$anim->create($frames, $durations, 5); // default: infinite looping ``` -**2. Get/use the result:** +**3. Get/use the result:** You can now get the animated GIF binary: From 007c734ad2293232fcef5915da6a1d31a0481658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 31 May 2014 10:34:19 +0200 Subject: [PATCH 115/120] Some clarifications --- README.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f6c2fc6..f761e4e 100644 --- a/README.md +++ b/README.md @@ -19,29 +19,28 @@ $frames = array( "http://thisisafakedomain.com/images/pic4.jpg", // URL ); -// Or, load the image files from a dir (sorted): +// Or: load images from a dir (sorted, skipping .files): //$frames = "../images"; -// Optionally, set the duration (in 1/100s units) for each frame +// Optionally: set different durations (in 1/100s units) for each frame $durations = array(20, 30, 10, 10); -// Or, with the shorthand form (omitting the repetitions): -//$durations = array(20, 30, 10); -// Or, even: +// Or: you can leave off repeated values from the end: +//$durations = array(20, 30, 10); // use 10 for the rest +// Or: use 'null' anywhere to re-apply the previous delay: //$durations = array(250, null, null, 500); ``` **2. Create the GIF:** ``` php -// Initialize and create the GIF! $anim = new GifCreator\AnimGif(); $anim->create($frames, $durations); -// Or, for just use a default 100ms even delay: +// Or: using the default 100ms even delay: //$anim->create($frames); -// Or, for 5 repeats & then stop: +// Or: loop 5 times, then stop: //$anim->create($frames, $durations, 5); // default: infinite looping ``` From 8a298df775ac8bbc0b0b8a84b98eb3d107a34125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Sat, 31 May 2014 10:35:10 +0200 Subject: [PATCH 116/120] Todo item added --- CHANGES.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index ea1de73..4bd8c64 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,7 @@ TODO: +! Allow image dirs within the input list (array), too, not only instead of it. + ! In local testing I had a strange issue with by-frame delays: the first image eats up the first two delays, and is shown for the sum of those two numbers... :-o -> And I seem to be unable to reproduce it now! :-o From 3a385cb4dde9668672e3d81033aa4f885d743d1d Mon Sep 17 00:00:00 2001 From: Luke Stevenson Date: Thu, 13 Oct 2016 21:49:47 +1100 Subject: [PATCH 117/120] Fixes Non-Looped GIFs Now allows for a GIF which does not loop to be created. --- src/GifCreator/AnimGif.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 029c6c9..635ed29 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -300,7 +300,9 @@ protected function gifAddHeader() $this->gif .= substr($this->frameSources[0], 6, 7); $this->gif .= substr($this->frameSources[0], 13, $cmap); - $this->gif .= "!\377\13NETSCAPE2.0\3\1".word2bin($this->loop)."\0"; + + if( $this->loop !== 1 ) + $this->gif .= "!\377\13NETSCAPE2.0\3\1".word2bin($this->loop)."\0"; } } From 9c81a3ab02617541b71e72ad132a93702eba4812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Mon, 6 Mar 2017 18:54:41 +0100 Subject: [PATCH 118/120] Cosmetics Fixed/updated/added some random comments. Changed spacing of + added comment to the no-loop contribution (thanks @lucanos!). (Also changed the old octals there to hex for consistency.) --- src/GifCreator/AnimGif.php | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 635ed29..0efb984 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -5,13 +5,13 @@ See CHANGES.txt for TODO items and release notes! DONE: -+ See the GitHub commit log for a detailed change history! ++ See the GitHub commit log for the most recent (& most detailed) change history! -------- Old (pre-1.2) manual change log (partly parallel with the GitHub commit log): + Renamed encodeAsciiToChar() to word2bin() & fixed its description. + Added error + check: 'ERR04' => 'Loading from URLs is disabled by PHP.'. + file_exists() -> @is_readable() (Better to take no risk of any PHP output - in a raw GIF transfer...) + in a raw GIF HTTP response...) + Oops, also need to fix the default delay. And then also change it to 100ms. (Because browsers seem to have difficulties handling too fast animations.) + Anim delay doesn't seem to be set in ms, at all. :-o @@ -61,32 +61,32 @@ class AnimGif const DEFAULT_DURATION = 10; /** - * @var string The generated (binary) image + * @var string: The generated (binary) image */ private $gif; /** - * @var boolean Has the image been built or not + * @var boolean: Has an image (frame) been added already? */ private $imgBuilt; /** - * @var array Frames string sources + * @var array or string: Frame sources like filenames, URLs or a dir */ private $frameSources; /** - * @var integer Gif loop + * @var integer: Gif loop count */ private $loop; /** - * @var integer Gif dis [!!?] + * @var integer: Gif frame disposal method */ private $dis; /** - * @var integer Gif transparent color index + * @var integer: Gif transparent color index */ private $transparent_color; @@ -127,8 +127,9 @@ public function create($frames, $durations = self::DEFAULT_DURATION, $loop = 0) { $last_duration = self::DEFAULT_DURATION; // used only if $durations is an array - $this->loop = ($loop > -1) ? $loop : 0; - $this->dis = 2; + $this->loop = ($loop > -1) ? $loop : 0; // Negatives would be fine for the GIF istelf (all unsigned!), + // but better not take a chance with the bit-ops etc. later. + $this->dis = 2; // "reset to bgnd." (http://www.matthewflickinger.com/lab/whatsinagif/animation_and_transparency.asp) // Check if $frames is a dir; get all files in ascending order if yes (else die): if (!is_array($frames)) { @@ -145,9 +146,9 @@ public function create($frames, $durations = self::DEFAULT_DURATION, $loop = 0) } } - if (!is_array($frames)) { + if (!is_array($frames)) { //!! throw new \Exception(VERSION.': ' - . sprintf(self::$errors['ERR05'], $frames_dir)); // $frame is expected to be a string here; see the other ERR05 case! + . sprintf(self::$errors['ERR05'], $frames_dir)); // $frames is expected to be a string here; see the other ERR05 case! } } @@ -233,7 +234,7 @@ public function create($frames, $durations = self::DEFAULT_DURATION, $loop = 0) for ($i = 0; $i < count($this->frameSources); $i++) { - // Use the last delay, if none has been specified for the current frame + // Re-use the last delay if none has been specified for the current frame. if (is_array($durations)) { $d = (empty($durations[$i]) ? $last_duration : $durations[$i]); $last_duration = $d; @@ -300,17 +301,16 @@ protected function gifAddHeader() $this->gif .= substr($this->frameSources[0], 6, 7); $this->gif .= substr($this->frameSources[0], 13, $cmap); - - if( $this->loop !== 1 ) - $this->gif .= "!\377\13NETSCAPE2.0\3\1".word2bin($this->loop)."\0"; + if ($this->loop !== 1) // Only add the looping extension if really looping + $this->gif .= "!\xFF\x0BNETSCAPE2.0\0x03\0x01".word2bin($this->loop)."\x0"; } } /** * Add the frame sources to the GIF string * - * @param integer $i - * @param integer $d + * @param integer $i: index of frame source + * @param integer $d: delay time (frame display duration) */ protected function addGifFrames($i, $d) { @@ -403,7 +403,7 @@ protected function gifAddFooter() } /** - * Compare two block and return the version + * Compare two blocks and return 1 if they are equal, 0 if differ. * * @param string $globalBlock * @param string $localBlock From 0b388f5af742da1b4cace93db0fb16d3ed19932b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C3=A1sz?= Date: Tue, 7 Mar 2017 04:21:30 +0100 Subject: [PATCH 119/120] Some more redundant pondering while watching an 1969 absurd movie... ...with Peter Sellers, Ringo Star, John Cleese, Graham Chapman and others (like Richard Attenborough and Roman polanski): The Magic Christian. Do check it out, it's amazingly embarrassing and delightful ad the same time! :) --- src/GifCreator/AnimGif.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 0efb984..af83ce7 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -71,7 +71,7 @@ class AnimGif private $imgBuilt; /** - * @var array or string: Frame sources like filenames, URLs or a dir + * @var array or string: Frame sources like filenames, URLs, bin. data, or a folder name */ private $frameSources; @@ -119,7 +119,7 @@ public function __construct() * of file paths, resource image variables, binary data or image URLs. * @param array|number $durations The duration (in 1/100s) of the individual frames, * or a single integer for each one. - * @param integer $loop Number of loops before stopping the animation (set to 0 for an infinite loop). + * @param integer $loop Number of loops before stopping the animation (set to 0 for infinite looping). * * @return string The resulting GIF binary data. */ @@ -127,8 +127,8 @@ public function create($frames, $durations = self::DEFAULT_DURATION, $loop = 0) { $last_duration = self::DEFAULT_DURATION; // used only if $durations is an array - $this->loop = ($loop > -1) ? $loop : 0; // Negatives would be fine for the GIF istelf (all unsigned!), - // but better not take a chance with the bit-ops etc. later. + $this->loop = ($loop > -1) ? $loop : 0; // Negatives would be fine for the GIF itself (all unsigned!), + // but better not take a chance with the PHP bit-ops... $this->dis = 2; // "reset to bgnd." (http://www.matthewflickinger.com/lab/whatsinagif/animation_and_transparency.asp) // Check if $frames is a dir; get all files in ascending order if yes (else die): @@ -146,7 +146,7 @@ public function create($frames, $durations = self::DEFAULT_DURATION, $loop = 0) } } - if (!is_array($frames)) { //!! + if (!is_array($frames)) { // i.e. scandir() failed above! throw new \Exception(VERSION.': ' . sprintf(self::$errors['ERR05'], $frames_dir)); // $frames is expected to be a string here; see the other ERR05 case! } @@ -234,7 +234,7 @@ public function create($frames, $durations = self::DEFAULT_DURATION, $loop = 0) for ($i = 0; $i < count($this->frameSources); $i++) { - // Re-use the last delay if none has been specified for the current frame. + // Reuse the last delay if none has been specified for the current frame. if (is_array($durations)) { $d = (empty($durations[$i]) ? $last_duration : $durations[$i]); $last_duration = $d; @@ -289,7 +289,7 @@ public function reset() // =================================================================================== /** - * Add the header gif string in its source + * Assemble the GIF header */ protected function gifAddHeader() { @@ -307,7 +307,7 @@ protected function gifAddHeader() } /** - * Add the frame sources to the GIF string + * Add frame to the GIF data * * @param integer $i: index of frame source * @param integer $d: delay time (frame display duration) From 76197caa3c1d76ed336af457fd1f7b34ab8a8a1d Mon Sep 17 00:00:00 2001 From: philklc Date: Wed, 25 Oct 2017 12:37:24 +0800 Subject: [PATCH 120/120] Corrected typo in GIF header generation, fixes #2 Also corrected is the loop value which should be zero based. --- src/GifCreator/AnimGif.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index af83ce7..727ac6c 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -302,7 +302,7 @@ protected function gifAddHeader() $this->gif .= substr($this->frameSources[0], 6, 7); $this->gif .= substr($this->frameSources[0], 13, $cmap); if ($this->loop !== 1) // Only add the looping extension if really looping - $this->gif .= "!\xFF\x0BNETSCAPE2.0\0x03\0x01".word2bin($this->loop)."\x0"; + $this->gif .= "!\xFF\x0BNETSCAPE2.0\x03\x01".word2bin($this->loop==0?0:$this->loop-1)."\x0"; } }