From 04e4b3bf072a3b6b682208e98f9f661638e3a372 Mon Sep 17 00:00:00 2001 From: Edmar Moretti Date: Wed, 16 Mar 2016 23:38:39 -0300 Subject: [PATCH] Ferramenta de Animacao no formato gif --- admin/admin.db | Bin 335872 -> 0 bytes ferramentas/animagif/exec.php | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pacotes/gifcreator/GifCreator.php | 358 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pacotes/gifcreator/README.md | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 617 insertions(+), 0 deletions(-) create mode 100755 ferramentas/animagif/exec.php create mode 100755 pacotes/gifcreator/GifCreator.php create mode 100755 pacotes/gifcreator/README.md diff --git a/admin/admin.db b/admin/admin.db index 9aa945b..1c6c8e7 100755 Binary files a/admin/admin.db and b/admin/admin.db differ diff --git a/ferramentas/animagif/exec.php b/ferramentas/animagif/exec.php new file mode 100755 index 0000000..359f357 --- /dev/null +++ b/ferramentas/animagif/exec.php @@ -0,0 +1,192 @@ +numlayers; +for ($i=0;$i < $numlayers;$i++){ + $layern = $mapa->getlayer($i); + if($layern->name != "copyright"){ + $layern->set("status",MS_DELETE); + } + else{ + $layern->set("status",MS_DEFAULT); + } +} +//ajusta o label +$l = $mapa->getlayerbyname("copyright"); +$classe = $l->getclass(0); +$label = $classe->getLabel(0); +$label->updatefromstring("LABEL TYPE TRUETYPE END"); +$label->set("font","arial"); +$label->set("size",15); +$label->updatefromstring("LABEL POSITION lr END"); +//$label->updatefromstring("LABEL OUTLINECOLOR 255 255 255 OUTLINEWIDTH 10 END"); +//$labels = new styleObj($classe); +$label->updatefromstring('LABEL STYLE GEOMTRANSFORM "labelpoly" COLOR 255 255 255 END END'); +// +$mapa->save($arqtemp.".map"); +//adiciona ao mapa base as camadas do mapfile indicado em $tema +$nmapa = ms_newMapObj($locaplic."/temas/".$tema.".map"); +$numlayers = $nmapa->numlayers; +for ($i=0;$i < $numlayers;$i++){ + $layern = $nmapa->getlayer($i); + $layern->set("status",MS_DEFAULT); + if (!empty($postgis_mapa)){ + if ($layern->connectiontype == MS_POSTGIS){ + $lcon = $layern->connection; + error_reporting(0); + if (($lcon == " ") || ($lcon == "") || (in_array($lcon,array_keys($postgis_mapa)))){ + if(($lcon == " ") || ($lcon == "")){ + $layern->set("connection",$postgis_mapa); + } + else{ + $layern->set("connection",$postgis_mapa[$lcon]); + } + } + } + } + autoClasses($layern,$nmapa); + cloneInlineSymbol($layern,$nmapa,$mapa); + ms_newLayerObj($mapa, $layern); +} +$mapa->save($arqtemp.".map"); +//aplica a extensao geografica +$layer = $mapa->getlayerbyname($tema); + +$extatual = $mapa->extent; +$ret = ""; +if(isset($mapext)){ + $ret = str_replace(","," ",$mapext); +} +else{ + $ret = $layer->getmetadata("extensao"); +} +if ($ret != ""){ + $ret = explode(" ",$ret); + $extatual->setextent($ret[0],$ret[1],$ret[2],$ret[3]); +} +$mapa->setsize($w,$h); +$sca = $mapa->scalebar; +$sca->set("status",MS_OFF); +$c = $mapa->imagecolor; +$c->setrgb(-1,-1,-1); +$o = $mapa->outputformat; +$o->set("imagemode",MS_IMAGEMODE_RGBA); +$o->set("transparent",MS_TRUE); +$mapa->save($arqtemp.".map"); +$mapa = ms_newMapObj($arqtemp.".map"); +if(validaAcessoTemas($arqtemp.".map",false) == true){ + echo "Existem temas restritos";exit; +} +//pega a lista de valores unicos da $colunat +include_once("../../classesphp/classe_atributos.php"); +$m = new Atributos($arqtemp.".map",$tema); +$lista = $m->listaRegistros($colunat,"mapa","sim",0,"","tudo","nao"); +$lista = $lista[1]["registros"]; +$listaunica = array(); +foreach($lista as $l){ + $v = $l["valores"][0]["valor"]; + if($v != ""){ + $listaunica[] = $v; + } +} +sort($listaunica); +//cria as imagens para cada periodo +$layer = $mapa->getlayerbyname($tema); + +$l = $mapa->getlayerbyname("copyright"); +$c = $l->getclass(0); +$label = $c->getLabel(0); + +$imagens = array(); +$duracao = array(); +$objImagem = ""; +//$listaunica = array($listaunica[1]); +foreach($listaunica as $d){ + $filtro = "(([$colunat] = $d))"; + $layer->setfilter($filtro); + $nomec = $arqtemp.$d.".png"; + + $s = "LABEL TEXT '".$d."' END"; + $label->updateFromString($s); + + if($objImagem == ""){ + $objImagem = $mapa->draw(); + $objImagem->saveImage($nomec); + } + else{ + $i = $mapa->draw(); + $objImagem->pasteImage($i,-1); + $objImagem->saveImage($nomec); + } + $imagens[] = $nomec; + $duracao[] = 40; +} +//junta as imagens no gif +include("../../pacotes/gifcreator/GifCreator.php"); +$gc = new GifCreator(); +$gc->create($imagens, $duracao, 1); +$gifBinary = $gc->getGif(); +//retorna o gif para o navegador +header('Content-type: image/gif'); +header('Content-Disposition: filename="butterfly.gif"'); +echo $gifBinary; +exit; +?> \ No newline at end of file diff --git a/pacotes/gifcreator/GifCreator.php b/pacotes/gifcreator/GifCreator.php new file mode 100755 index 0000000..4c484af --- /dev/null +++ b/pacotes/gifcreator/GifCreator.php @@ -0,0 +1,358 @@ +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) + */ + private $frameSources; + + /** + * @var integer Gif loop (old: this->LOP) + */ + private $loop; + + /** + * @var integer Gif dis (old: this->DIS) + */ + private $dis; + + /** + * @var integer Gif color (old: this->COL) + */ + private $colour; + + /** + * @var array (old: this->ERR) + */ + private $errors; + + // 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.', + ); + } + + /** + * 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']); + } + + $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 + + 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.')'); + } + + 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']); + } + + 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).'); + } + + break; + + case ';': + + $k = false; + break; + } + } + + unset($resourceImg); + } + + 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; + } + + // Internals + // =================================================================================== + + /** + * Add the header gif string in its source (old: GIFAddHeader) + */ + public function gifAddHeader() + { + $cmap = 0; + + if (ord($this->frameSources[0] { 10 }) & 0x80) { + + $cmap = 3 * (2 << (ord($this->frameSources[0] { 10 }) & 0x07)); + + $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"; + } + } + + /** + * 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; + $Locals_tmp = substr($this->frameSources[$i], $Locals_str, $Locals_end); + + $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))); + $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"; + + if ($this->colour > -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) + ) { + $Locals_ext = "!\xF9\x04".chr(($this->dis << 2) + 1).chr(($d >> 0) & 0xFF).chr(($d >> 8) & 0xFF).chr($j)."\x0"; + break; + } + } + } + + switch ($Locals_tmp { 0 }) { + + case '!': + + $Locals_img = substr($Locals_tmp, 8, 10); + $Locals_tmp = substr($Locals_tmp, 18, strlen($Locals_tmp) - 18); + + break; + + case ',': + + $Locals_img = substr($Locals_tmp, 0, 10); + $Locals_tmp = substr($Locals_tmp, 10, strlen($Locals_tmp) - 10); + + break; + } + + if (ord($this->frameSources[$i] { 10 }) & 0x80 && $this->imgBuilt) { + + if ($Global_len == $Locals_len) { + + if ($this->gifBlockCompare($Global_rgb, $Locals_rgb, $Global_len)) { + + $this->gif .= $Locals_ext.$Locals_img.$Locals_tmp; + + } else { + + $byte = ord($Locals_img { 9 }); + $byte |= 0x80; + $byte &= 0xF8; + $byte |= (ord($this->frameSources[0] { 10 }) & 0x07); + $Locals_img { 9 } = chr($byte); + $this->gif .= $Locals_ext.$Locals_img.$Locals_rgb.$Locals_tmp; + } + + } else { + + $byte = ord($Locals_img { 9 }); + $byte |= 0x80; + $byte &= 0xF8; + $byte |= (ord($this->frameSources[$i] { 10 }) & 0x07); + $Locals_img { 9 } = chr($byte); + $this->gif .= $Locals_ext.$Locals_img.$Locals_rgb.$Locals_tmp; + } + + } else { + + $this->gif .= $Locals_ext.$Locals_img.$Locals_tmp; + } + + $this->imgBuilt = true; + } + + /** + * 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 + */ + 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 }) { + + 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; + } +} +?> diff --git a/pacotes/gifcreator/README.md b/pacotes/gifcreator/README.md new file mode 100755 index 0000000..847eb0d --- /dev/null +++ b/pacotes/gifcreator/README.md @@ -0,0 +1,67 @@ +# ================================ +# GifCreator +# ================================ + +GifCreator is a PHP class to create 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 ! + +### Usage + +**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. +$frames = array( + imagecreatefrompng("/../images/pic1.png"), // Resource var + "/../images/pic2.png", // Image file path + file_get_contents("/../images/pic3.jpg"), // Binary source code + 'http://thisisafakedomain.com/images/pic4.jpg', // URL +); + +// Create an array containing the duration (in millisecond) of each frames (in order too) +$durations = array(40, 80, 40, 20); + +// Initialize and create the GIF ! +$gc = new GifCreator(); +$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. +In the previous example, I chose 5 loops. Set 0 (zero) to get an infinite loop. + +**2 - Get the result:** + +You can now get the animated GIF binary: + +```php +$gifBinary = $gc->getGif(); +``` + +Then you can show it in the navigator: + +```php +header('Content-type: image/gif'); +header('Content-Disposition: filename="butterfly.gif"'); +echo $gifBinary; +exit; +``` + +Or save it in a folder as a GIF: + +```php +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 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 + +The class reuses some part of code of "GIFEncoder.class.php" by László Zsidi (thanks to him). \ No newline at end of file -- libgit2 0.21.2