Commit 3bfa154e02b21ba664f01163ff569216142c3b1d
1 parent
fa188761
Exists in
master
Ferramenta de Animacao no formato gif
Showing
3 changed files
with
617 additions
and
0 deletions
Show diff stats
@@ -0,0 +1,192 @@ | @@ -0,0 +1,192 @@ | ||
1 | +<?php | ||
2 | +//$tema - nome do mapfile | ||
3 | +//$colunat - coluna que contem os periodos | ||
4 | +//$tempo - tempo entre os frames | ||
5 | +//$w | ||
6 | +//$h | ||
7 | +//$cache | ||
8 | +//$mapext | ||
9 | +//http://localhost/i3geo/ferramentas/animagif/exec.php?tema=_llocali&colunat=ANOCRIA&w=500&h=500&mapext=-72%20-33%20-32%204 | ||
10 | +include("../../ms_configura.php"); | ||
11 | +include("../../classesphp/funcoes_gerais.php"); | ||
12 | +include("../../classesphp/pega_variaveis.php"); | ||
13 | +include("../../classesphp/carrega_ext.php"); | ||
14 | +$nometemp = nomeRandomico(); | ||
15 | +$arqtemp = $dir_tmp."/".$nometemp; | ||
16 | +// | ||
17 | +//carrega o phpmapscript | ||
18 | +// | ||
19 | +if (!function_exists('ms_GetVersion')) | ||
20 | +{ | ||
21 | + if (strtoupper(substr(PHP_OS, 0, 3) == 'WIN')) | ||
22 | + { | ||
23 | + if(!@dl('php_mapscript_48.dll')) | ||
24 | + dl('php_mapscript.dll'); | ||
25 | + } | ||
26 | + else | ||
27 | + {dl('php_mapscript.so'); | ||
28 | + } | ||
29 | +} | ||
30 | +$versao = versao(); | ||
31 | +$versao = $versao["principal"]; | ||
32 | + | ||
33 | +//cria um mapa temporario | ||
34 | +if($base == "" or !isset($base)){ | ||
35 | + $base = ""; | ||
36 | + if (strtoupper(substr(PHP_OS, 0, 3) == 'WIN')){ | ||
37 | + $base = $locaplic."/aplicmap/geral1windowsv".$versao.".map"; | ||
38 | + } | ||
39 | + else{ | ||
40 | + if($base == "" && file_exists('/var/www/i3geo/aplicmap/geral1debianv'.$versao.'.map')){ | ||
41 | + $base = "/var/www/i3geo/aplicmap/geral1debianv".$versao.".map"; | ||
42 | + } | ||
43 | + if($base == "" && file_exists('/var/www/html/i3geo/aplicmap/geral1fedorav'.$versao.'.map')){ | ||
44 | + $base = "/var/www/html/i3geo/aplicmap/geral1fedorav".$versao.".map"; | ||
45 | + } | ||
46 | + if($base == "" && file_exists('/opt/www/html/i3geo/aplicmap/geral1fedorav'.$versao.'.map')){ | ||
47 | + $base = "/opt/www/html/i3geo/aplicmap/geral1v".$versao.".map"; | ||
48 | + } | ||
49 | + if($base == ""){ | ||
50 | + $base = $locaplic."/aplicmap/geral1v".$versao.".map"; | ||
51 | + } | ||
52 | + } | ||
53 | +} | ||
54 | +else{ | ||
55 | + if(!file_exists($base)){ | ||
56 | + $base = $locaplic."/aplicmap/".$base; | ||
57 | + } | ||
58 | +} | ||
59 | +$mapa = ms_newMapObj($base); | ||
60 | + | ||
61 | +//remove as camadas do mapa base | ||
62 | +$numlayers = $mapa->numlayers; | ||
63 | +for ($i=0;$i < $numlayers;$i++){ | ||
64 | + $layern = $mapa->getlayer($i); | ||
65 | + if($layern->name != "copyright"){ | ||
66 | + $layern->set("status",MS_DELETE); | ||
67 | + } | ||
68 | + else{ | ||
69 | + $layern->set("status",MS_DEFAULT); | ||
70 | + } | ||
71 | +} | ||
72 | +//ajusta o label | ||
73 | +$l = $mapa->getlayerbyname("copyright"); | ||
74 | +$classe = $l->getclass(0); | ||
75 | +$label = $classe->getLabel(0); | ||
76 | +$label->updatefromstring("LABEL TYPE TRUETYPE END"); | ||
77 | +$label->set("font","arial"); | ||
78 | +$label->set("size",15); | ||
79 | +$label->updatefromstring("LABEL POSITION lr END"); | ||
80 | +//$label->updatefromstring("LABEL OUTLINECOLOR 255 255 255 OUTLINEWIDTH 10 END"); | ||
81 | +//$labels = new styleObj($classe); | ||
82 | +$label->updatefromstring('LABEL STYLE GEOMTRANSFORM "labelpoly" COLOR 255 255 255 END END'); | ||
83 | +// | ||
84 | +$mapa->save($arqtemp.".map"); | ||
85 | +//adiciona ao mapa base as camadas do mapfile indicado em $tema | ||
86 | +$nmapa = ms_newMapObj($locaplic."/temas/".$tema.".map"); | ||
87 | +$numlayers = $nmapa->numlayers; | ||
88 | +for ($i=0;$i < $numlayers;$i++){ | ||
89 | + $layern = $nmapa->getlayer($i); | ||
90 | + $layern->set("status",MS_DEFAULT); | ||
91 | + if (!empty($postgis_mapa)){ | ||
92 | + if ($layern->connectiontype == MS_POSTGIS){ | ||
93 | + $lcon = $layern->connection; | ||
94 | + error_reporting(0); | ||
95 | + if (($lcon == " ") || ($lcon == "") || (in_array($lcon,array_keys($postgis_mapa)))){ | ||
96 | + if(($lcon == " ") || ($lcon == "")){ | ||
97 | + $layern->set("connection",$postgis_mapa); | ||
98 | + } | ||
99 | + else{ | ||
100 | + $layern->set("connection",$postgis_mapa[$lcon]); | ||
101 | + } | ||
102 | + } | ||
103 | + } | ||
104 | + } | ||
105 | + autoClasses($layern,$nmapa); | ||
106 | + cloneInlineSymbol($layern,$nmapa,$mapa); | ||
107 | + ms_newLayerObj($mapa, $layern); | ||
108 | +} | ||
109 | +$mapa->save($arqtemp.".map"); | ||
110 | +//aplica a extensao geografica | ||
111 | +$layer = $mapa->getlayerbyname($tema); | ||
112 | + | ||
113 | +$extatual = $mapa->extent; | ||
114 | +$ret = ""; | ||
115 | +if(isset($mapext)){ | ||
116 | + $ret = str_replace(","," ",$mapext); | ||
117 | +} | ||
118 | +else{ | ||
119 | + $ret = $layer->getmetadata("extensao"); | ||
120 | +} | ||
121 | +if ($ret != ""){ | ||
122 | + $ret = explode(" ",$ret); | ||
123 | + $extatual->setextent($ret[0],$ret[1],$ret[2],$ret[3]); | ||
124 | +} | ||
125 | +$mapa->setsize($w,$h); | ||
126 | +$sca = $mapa->scalebar; | ||
127 | +$sca->set("status",MS_OFF); | ||
128 | +$c = $mapa->imagecolor; | ||
129 | +$c->setrgb(-1,-1,-1); | ||
130 | +$o = $mapa->outputformat; | ||
131 | +$o->set("imagemode",MS_IMAGEMODE_RGBA); | ||
132 | +$o->set("transparent",MS_TRUE); | ||
133 | +$mapa->save($arqtemp.".map"); | ||
134 | +$mapa = ms_newMapObj($arqtemp.".map"); | ||
135 | +if(validaAcessoTemas($arqtemp.".map",false) == true){ | ||
136 | + echo "Existem temas restritos";exit; | ||
137 | +} | ||
138 | +//pega a lista de valores unicos da $colunat | ||
139 | +include_once("../../classesphp/classe_atributos.php"); | ||
140 | +$m = new Atributos($arqtemp.".map",$tema); | ||
141 | +$lista = $m->listaRegistros($colunat,"mapa","sim",0,"","tudo","nao"); | ||
142 | +$lista = $lista[1]["registros"]; | ||
143 | +$listaunica = array(); | ||
144 | +foreach($lista as $l){ | ||
145 | + $v = $l["valores"][0]["valor"]; | ||
146 | + if($v != ""){ | ||
147 | + $listaunica[] = $v; | ||
148 | + } | ||
149 | +} | ||
150 | +sort($listaunica); | ||
151 | +//cria as imagens para cada periodo | ||
152 | +$layer = $mapa->getlayerbyname($tema); | ||
153 | + | ||
154 | +$l = $mapa->getlayerbyname("copyright"); | ||
155 | +$c = $l->getclass(0); | ||
156 | +$label = $c->getLabel(0); | ||
157 | + | ||
158 | +$imagens = array(); | ||
159 | +$duracao = array(); | ||
160 | +$objImagem = ""; | ||
161 | +//$listaunica = array($listaunica[1]); | ||
162 | +foreach($listaunica as $d){ | ||
163 | + $filtro = "(([$colunat] = $d))"; | ||
164 | + $layer->setfilter($filtro); | ||
165 | + $nomec = $arqtemp.$d.".png"; | ||
166 | + | ||
167 | + $s = "LABEL TEXT '".$d."' END"; | ||
168 | + $label->updateFromString($s); | ||
169 | + | ||
170 | + if($objImagem == ""){ | ||
171 | + $objImagem = $mapa->draw(); | ||
172 | + $objImagem->saveImage($nomec); | ||
173 | + } | ||
174 | + else{ | ||
175 | + $i = $mapa->draw(); | ||
176 | + $objImagem->pasteImage($i,-1); | ||
177 | + $objImagem->saveImage($nomec); | ||
178 | + } | ||
179 | + $imagens[] = $nomec; | ||
180 | + $duracao[] = 40; | ||
181 | +} | ||
182 | +//junta as imagens no gif | ||
183 | +include("../../pacotes/gifcreator/GifCreator.php"); | ||
184 | +$gc = new GifCreator(); | ||
185 | +$gc->create($imagens, $duracao, 1); | ||
186 | +$gifBinary = $gc->getGif(); | ||
187 | +//retorna o gif para o navegador | ||
188 | +header('Content-type: image/gif'); | ||
189 | +header('Content-Disposition: filename="butterfly.gif"'); | ||
190 | +echo $gifBinary; | ||
191 | +exit; | ||
192 | +?> | ||
0 | \ No newline at end of file | 193 | \ No newline at end of file |
@@ -0,0 +1,358 @@ | @@ -0,0 +1,358 @@ | ||
1 | +<?php | ||
2 | + | ||
3 | + | ||
4 | + | ||
5 | +/** | ||
6 | + * Create an animated GIF from multiple images | ||
7 | + * | ||
8 | + * @version 1.0 | ||
9 | + * @link https://github.com/Sybio/GifCreator | ||
10 | + * @author Sybio (Clément Guillemain / @Sybio01) | ||
11 | + * @license http://opensource.org/licenses/gpl-license.php GNU Public License | ||
12 | + * @copyright Clément Guillemain | ||
13 | + */ | ||
14 | +class GifCreator | ||
15 | +{ | ||
16 | + /** | ||
17 | + * @var string The gif string source (old: this->GIF) | ||
18 | + */ | ||
19 | + private $gif; | ||
20 | + | ||
21 | + /** | ||
22 | + * @var string Encoder version (old: this->VER) | ||
23 | + */ | ||
24 | + private $version; | ||
25 | + | ||
26 | + /** | ||
27 | + * @var boolean Check the image is build or not (old: this->IMG) | ||
28 | + */ | ||
29 | + private $imgBuilt; | ||
30 | + | ||
31 | + /** | ||
32 | + * @var array Frames string sources (old: this->BUF) | ||
33 | + */ | ||
34 | + private $frameSources; | ||
35 | + | ||
36 | + /** | ||
37 | + * @var integer Gif loop (old: this->LOP) | ||
38 | + */ | ||
39 | + private $loop; | ||
40 | + | ||
41 | + /** | ||
42 | + * @var integer Gif dis (old: this->DIS) | ||
43 | + */ | ||
44 | + private $dis; | ||
45 | + | ||
46 | + /** | ||
47 | + * @var integer Gif color (old: this->COL) | ||
48 | + */ | ||
49 | + private $colour; | ||
50 | + | ||
51 | + /** | ||
52 | + * @var array (old: this->ERR) | ||
53 | + */ | ||
54 | + private $errors; | ||
55 | + | ||
56 | + // Methods | ||
57 | + // =================================================================================== | ||
58 | + | ||
59 | + /** | ||
60 | + * Constructor | ||
61 | + */ | ||
62 | + public function __construct() | ||
63 | + { | ||
64 | + $this->reset(); | ||
65 | + | ||
66 | + // Static data | ||
67 | + $this->version = 'GifCreator: Under development'; | ||
68 | + $this->errors = array( | ||
69 | + 'ERR00' => 'Does not supported function for only one image.', | ||
70 | + 'ERR01' => 'Source is not a GIF image.', | ||
71 | + 'ERR02' => 'You have to give resource image variables, image URL or image binary sources in $frames array.', | ||
72 | + 'ERR03' => 'Does not make animation from animated GIF source.', | ||
73 | + ); | ||
74 | + } | ||
75 | + | ||
76 | + /** | ||
77 | + * Create the GIF string (old: GIFEncoder) | ||
78 | + * | ||
79 | + * @param array $frames An array of frame: can be file paths, resource image variables, binary sources or image URLs | ||
80 | + * @param array $durations An array containing the duration of each frame | ||
81 | + * @param integer $loop Number of GIF loops before stopping animation (Set 0 to get an infinite loop) | ||
82 | + * | ||
83 | + * @return string The GIF string source | ||
84 | + */ | ||
85 | + public function create($frames = array(), $durations = array(), $loop = 0) | ||
86 | + { | ||
87 | + if (!is_array($frames) && !is_array($GIF_tim)) { | ||
88 | + | ||
89 | + throw new \Exception($this->version.': '.$this->errors['ERR00']); | ||
90 | + } | ||
91 | + | ||
92 | + $this->loop = ($loop > -1) ? $loop : 0; | ||
93 | + $this->dis = 2; | ||
94 | + | ||
95 | + for ($i = 0; $i < count($frames); $i++) { | ||
96 | + | ||
97 | + if (is_resource($frames[$i])) { // Resource var | ||
98 | + | ||
99 | + $resourceImg = $frames[$i]; | ||
100 | + | ||
101 | + ob_start(); | ||
102 | + imagegif($frames[$i]); | ||
103 | + $this->frameSources[] = ob_get_contents(); | ||
104 | + ob_end_clean(); | ||
105 | + | ||
106 | + } elseif (is_string($frames[$i])) { // File path or URL or Binary source code | ||
107 | + | ||
108 | + if (file_exists($frames[$i]) || filter_var($frames[$i], FILTER_VALIDATE_URL)) { // File path | ||
109 | + | ||
110 | + $frames[$i] = file_get_contents($frames[$i]); | ||
111 | + } | ||
112 | + | ||
113 | + $resourceImg = imagecreatefromstring($frames[$i]); | ||
114 | + | ||
115 | + ob_start(); | ||
116 | + imagegif($resourceImg); | ||
117 | + $this->frameSources[] = ob_get_contents(); | ||
118 | + ob_end_clean(); | ||
119 | + | ||
120 | + } else { // Fail | ||
121 | + | ||
122 | + throw new \Exception($this->version.': '.$this->errors['ERR02'].' ('.$mode.')'); | ||
123 | + } | ||
124 | + | ||
125 | + if ($i == 0) { | ||
126 | + | ||
127 | + $colour = imagecolortransparent($resourceImg); | ||
128 | + } | ||
129 | + | ||
130 | + if (substr($this->frameSources[$i], 0, 6) != 'GIF87a' && substr($this->frameSources[$i], 0, 6) != 'GIF89a') { | ||
131 | + | ||
132 | + throw new \Exception($this->version.': '.$i.' '.$this->errors['ERR01']); | ||
133 | + } | ||
134 | + | ||
135 | + for ($j = (13 + 3 * (2 << (ord($this->frameSources[$i] { 10 }) & 0x07))), $k = TRUE; $k; $j++) { | ||
136 | + | ||
137 | + switch ($this->frameSources[$i] { $j }) { | ||
138 | + | ||
139 | + case '!': | ||
140 | + | ||
141 | + if ((substr($this->frameSources[$i], ($j + 3), 8)) == 'NETSCAPE') { | ||
142 | + | ||
143 | + throw new \Exception($this->version.': '.$this->errors['ERR03'].' ('.($i + 1).' source).'); | ||
144 | + } | ||
145 | + | ||
146 | + break; | ||
147 | + | ||
148 | + case ';': | ||
149 | + | ||
150 | + $k = false; | ||
151 | + break; | ||
152 | + } | ||
153 | + } | ||
154 | + | ||
155 | + unset($resourceImg); | ||
156 | + } | ||
157 | + | ||
158 | + if (isset($colour)) { | ||
159 | + | ||
160 | + $this->colour = $colour; | ||
161 | + | ||
162 | + } else { | ||
163 | + | ||
164 | + $red = $green = $blue = 0; | ||
165 | + $this->colour = ($red > -1 && $green > -1 && $blue > -1) ? ($red | ($green << 8) | ($blue << 16)) : -1; | ||
166 | + } | ||
167 | + | ||
168 | + $this->gifAddHeader(); | ||
169 | + | ||
170 | + for ($i = 0; $i < count($this->frameSources); $i++) { | ||
171 | + | ||
172 | + $this->addGifFrames($i, $durations[$i]); | ||
173 | + } | ||
174 | + | ||
175 | + $this->gifAddFooter(); | ||
176 | + | ||
177 | + return $this->gif; | ||
178 | + } | ||
179 | + | ||
180 | + // Internals | ||
181 | + // =================================================================================== | ||
182 | + | ||
183 | + /** | ||
184 | + * Add the header gif string in its source (old: GIFAddHeader) | ||
185 | + */ | ||
186 | + public function gifAddHeader() | ||
187 | + { | ||
188 | + $cmap = 0; | ||
189 | + | ||
190 | + if (ord($this->frameSources[0] { 10 }) & 0x80) { | ||
191 | + | ||
192 | + $cmap = 3 * (2 << (ord($this->frameSources[0] { 10 }) & 0x07)); | ||
193 | + | ||
194 | + $this->gif .= substr($this->frameSources[0], 6, 7); | ||
195 | + $this->gif .= substr($this->frameSources[0], 13, $cmap); | ||
196 | + $this->gif .= "!\377\13NETSCAPE2.0\3\1".$this->encodeAsciiToChar($this->loop)."\0"; | ||
197 | + } | ||
198 | + } | ||
199 | + | ||
200 | + /** | ||
201 | + * Add the frame sources to the GIF string (old: GIFAddFrames) | ||
202 | + * | ||
203 | + * @param integer $i | ||
204 | + * @param integer $d | ||
205 | + */ | ||
206 | + public function addGifFrames($i, $d) | ||
207 | + { | ||
208 | + $Locals_str = 13 + 3 * (2 << (ord($this->frameSources[ $i ] { 10 }) & 0x07)); | ||
209 | + | ||
210 | + $Locals_end = strlen($this->frameSources[$i]) - $Locals_str - 1; | ||
211 | + $Locals_tmp = substr($this->frameSources[$i], $Locals_str, $Locals_end); | ||
212 | + | ||
213 | + $Global_len = 2 << (ord($this->frameSources[0 ] { 10 }) & 0x07); | ||
214 | + $Locals_len = 2 << (ord($this->frameSources[$i] { 10 }) & 0x07); | ||
215 | + | ||
216 | + $Global_rgb = substr($this->frameSources[0], 13, 3 * (2 << (ord($this->frameSources[0] { 10 }) & 0x07))); | ||
217 | + $Locals_rgb = substr($this->frameSources[$i], 13, 3 * (2 << (ord($this->frameSources[$i] { 10 }) & 0x07))); | ||
218 | + | ||
219 | + $Locals_ext = "!\xF9\x04".chr(($this->dis << 2) + 0).chr(($d >> 0 ) & 0xFF).chr(($d >> 8) & 0xFF)."\x0\x0"; | ||
220 | + | ||
221 | + if ($this->colour > -1 && ord($this->frameSources[$i] { 10 }) & 0x80) { | ||
222 | + | ||
223 | + for ($j = 0; $j < (2 << (ord($this->frameSources[$i] { 10 } ) & 0x07)); $j++) { | ||
224 | + | ||
225 | + if (ord($Locals_rgb { 3 * $j + 0 }) == (($this->colour >> 16) & 0xFF) && | ||
226 | + ord($Locals_rgb { 3 * $j + 1 }) == (($this->colour >> 8) & 0xFF) && | ||
227 | + ord($Locals_rgb { 3 * $j + 2 }) == (($this->colour >> 0) & 0xFF) | ||
228 | + ) { | ||
229 | + $Locals_ext = "!\xF9\x04".chr(($this->dis << 2) + 1).chr(($d >> 0) & 0xFF).chr(($d >> 8) & 0xFF).chr($j)."\x0"; | ||
230 | + break; | ||
231 | + } | ||
232 | + } | ||
233 | + } | ||
234 | + | ||
235 | + switch ($Locals_tmp { 0 }) { | ||
236 | + | ||
237 | + case '!': | ||
238 | + | ||
239 | + $Locals_img = substr($Locals_tmp, 8, 10); | ||
240 | + $Locals_tmp = substr($Locals_tmp, 18, strlen($Locals_tmp) - 18); | ||
241 | + | ||
242 | + break; | ||
243 | + | ||
244 | + case ',': | ||
245 | + | ||
246 | + $Locals_img = substr($Locals_tmp, 0, 10); | ||
247 | + $Locals_tmp = substr($Locals_tmp, 10, strlen($Locals_tmp) - 10); | ||
248 | + | ||
249 | + break; | ||
250 | + } | ||
251 | + | ||
252 | + if (ord($this->frameSources[$i] { 10 }) & 0x80 && $this->imgBuilt) { | ||
253 | + | ||
254 | + if ($Global_len == $Locals_len) { | ||
255 | + | ||
256 | + if ($this->gifBlockCompare($Global_rgb, $Locals_rgb, $Global_len)) { | ||
257 | + | ||
258 | + $this->gif .= $Locals_ext.$Locals_img.$Locals_tmp; | ||
259 | + | ||
260 | + } else { | ||
261 | + | ||
262 | + $byte = ord($Locals_img { 9 }); | ||
263 | + $byte |= 0x80; | ||
264 | + $byte &= 0xF8; | ||
265 | + $byte |= (ord($this->frameSources[0] { 10 }) & 0x07); | ||
266 | + $Locals_img { 9 } = chr($byte); | ||
267 | + $this->gif .= $Locals_ext.$Locals_img.$Locals_rgb.$Locals_tmp; | ||
268 | + } | ||
269 | + | ||
270 | + } else { | ||
271 | + | ||
272 | + $byte = ord($Locals_img { 9 }); | ||
273 | + $byte |= 0x80; | ||
274 | + $byte &= 0xF8; | ||
275 | + $byte |= (ord($this->frameSources[$i] { 10 }) & 0x07); | ||
276 | + $Locals_img { 9 } = chr($byte); | ||
277 | + $this->gif .= $Locals_ext.$Locals_img.$Locals_rgb.$Locals_tmp; | ||
278 | + } | ||
279 | + | ||
280 | + } else { | ||
281 | + | ||
282 | + $this->gif .= $Locals_ext.$Locals_img.$Locals_tmp; | ||
283 | + } | ||
284 | + | ||
285 | + $this->imgBuilt = true; | ||
286 | + } | ||
287 | + | ||
288 | + /** | ||
289 | + * Add the gif string footer char (old: GIFAddFooter) | ||
290 | + */ | ||
291 | + public function gifAddFooter() | ||
292 | + { | ||
293 | + $this->gif .= ';'; | ||
294 | + } | ||
295 | + | ||
296 | + /** | ||
297 | + * Compare two block and return the version (old: GIFBlockCompare) | ||
298 | + * | ||
299 | + * @param string $globalBlock | ||
300 | + * @param string $localBlock | ||
301 | + * @param integer $length | ||
302 | + * | ||
303 | + * @return integer | ||
304 | + */ | ||
305 | + public function gifBlockCompare($globalBlock, $localBlock, $length) | ||
306 | + { | ||
307 | + for ($i = 0; $i < $length; $i++) { | ||
308 | + | ||
309 | + if ($globalBlock { 3 * $i + 0 } != $localBlock { 3 * $i + 0 } || | ||
310 | + $globalBlock { 3 * $i + 1 } != $localBlock { 3 * $i + 1 } || | ||
311 | + $globalBlock { 3 * $i + 2 } != $localBlock { 3 * $i + 2 }) { | ||
312 | + | ||
313 | + return 0; | ||
314 | + } | ||
315 | + } | ||
316 | + | ||
317 | + return 1; | ||
318 | + } | ||
319 | + | ||
320 | + /** | ||
321 | + * Encode an ASCII char into a string char (old: GIFWord) | ||
322 | + * | ||
323 | + * $param integer $char ASCII char | ||
324 | + * | ||
325 | + * @return string | ||
326 | + */ | ||
327 | + public function encodeAsciiToChar($char) | ||
328 | + { | ||
329 | + return (chr($char & 0xFF).chr(($char >> 8) & 0xFF)); | ||
330 | + } | ||
331 | + | ||
332 | + /** | ||
333 | + * Reset and clean the current object | ||
334 | + */ | ||
335 | + public function reset() | ||
336 | + { | ||
337 | + $this->frameSources; | ||
338 | + $this->gif = 'GIF89a'; // the GIF header | ||
339 | + $this->imgBuilt = false; | ||
340 | + $this->loop = 0; | ||
341 | + $this->dis = 2; | ||
342 | + $this->colour = -1; | ||
343 | + } | ||
344 | + | ||
345 | + // Getter / Setter | ||
346 | + // =================================================================================== | ||
347 | + | ||
348 | + /** | ||
349 | + * Get the final GIF image string (old: GetAnimation) | ||
350 | + * | ||
351 | + * @return string | ||
352 | + */ | ||
353 | + public function getGif() | ||
354 | + { | ||
355 | + return $this->gif; | ||
356 | + } | ||
357 | +} | ||
358 | +?> |
@@ -0,0 +1,67 @@ | @@ -0,0 +1,67 @@ | ||
1 | +# ================================ | ||
2 | +# GifCreator | ||
3 | +# ================================ | ||
4 | + | ||
5 | +GifCreator is a PHP class to create animated GIF from multiple images | ||
6 | + | ||
7 | +### For what ? | ||
8 | + | ||
9 | +This class helps you to create an animated GIF image: give multiple images and their duration and that's it ! | ||
10 | + | ||
11 | +### Usage | ||
12 | + | ||
13 | +**1 - Creation:** | ||
14 | + | ||
15 | +```php | ||
16 | +// Create an array containing file paths, resource var (initialized with imagecreatefromXXX), | ||
17 | +// image URLs or even binary code from image files. | ||
18 | +// All sorted in order to appear. | ||
19 | +$frames = array( | ||
20 | + imagecreatefrompng("/../images/pic1.png"), // Resource var | ||
21 | + "/../images/pic2.png", // Image file path | ||
22 | + file_get_contents("/../images/pic3.jpg"), // Binary source code | ||
23 | + 'http://thisisafakedomain.com/images/pic4.jpg', // URL | ||
24 | +); | ||
25 | + | ||
26 | +// Create an array containing the duration (in millisecond) of each frames (in order too) | ||
27 | +$durations = array(40, 80, 40, 20); | ||
28 | + | ||
29 | +// Initialize and create the GIF ! | ||
30 | +$gc = new GifCreator(); | ||
31 | +$gc->create($frames, $durations, 5); | ||
32 | +``` | ||
33 | +The 3rd parameter of create() method allows you to choose the number of loop of your animated gif before it stops. | ||
34 | +In the previous example, I chose 5 loops. Set 0 (zero) to get an infinite loop. | ||
35 | + | ||
36 | +**2 - Get the result:** | ||
37 | + | ||
38 | +You can now get the animated GIF binary: | ||
39 | + | ||
40 | +```php | ||
41 | +$gifBinary = $gc->getGif(); | ||
42 | +``` | ||
43 | + | ||
44 | +Then you can show it in the navigator: | ||
45 | + | ||
46 | +```php | ||
47 | +header('Content-type: image/gif'); | ||
48 | +header('Content-Disposition: filename="butterfly.gif"'); | ||
49 | +echo $gifBinary; | ||
50 | +exit; | ||
51 | +``` | ||
52 | + | ||
53 | +Or save it in a folder as a GIF: | ||
54 | + | ||
55 | +```php | ||
56 | +file_put_contents('/myfolder/animated_picture.gif', $gifBinary); | ||
57 | +``` | ||
58 | + | ||
59 | +### Behavior | ||
60 | + | ||
61 | +- The transparency is based on the first given frame. It will be saved only if you give multiple frames with same transparent background. | ||
62 | +- 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 | ||
63 | +this class: https://github.com/Sybio/ImageWorkshop | ||
64 | + | ||
65 | +### About | ||
66 | + | ||
67 | +The class reuses some part of code of "GIFEncoder.class.php" by László Zsidi (thanks to him). | ||
0 | \ No newline at end of file | 68 | \ No newline at end of file |