Pergunta

Eu preciso para redimensionar um arquivo GIF animado sem destruir a animação.

Como posso fazê-lo usando PHP?

Foi útil?

Solução

Se você tem acesso imagemagick, você pode fazer isso:

system("convert big.gif -coalesce coalesce.gif");
system("convert -size 200x100 coalesce.gif -resize 200x10 small.gif");

este é provavelmente possível com o plugin imagemagick se você não tem system () acesso

NOTA:. Isso pode criar um tamanho de arquivo maior imagem de dimensões menores embora devido a coalescência essencialmente deoptimizing a imagem

UPDATE: Se você não tem acesso ImageMagick, você deve ser capaz de usar uma combinação das seguintes etapas para redimensionar um gif animado (supondo que você tem acesso GD):

  1. Detectar se a imagem é um GIF animado: Can I detectar gifs animados usando php e gd? (resposta superior)
  2. Split o GIF animado em quadros individuais: http://www.phpclasses.org/package/3234-PHP-Split-GIF-animations-into-multiple-images.html
  3. redimensionar a quadros individuais: http://www.akemapa.com/2008/07/10/php-gd-resize-transparent-image-png-gif/
  4. Recomposite os quadros em um GIF animado de novo: http://www.phpclasses.org/package/3163-PHP-Generate-GIF-animations-from-a-set-of-GIF-images.html

Este é definitivamente muito mais intensiva do que a rota ImageMagick, mas deve ser tecnicamente possível.

Se você fazê-lo funcionar, por favor, compartilhe com o mundo!

Outras dicas

Tente GDEnhancer (Use Imagecraft ). Ele só precisa de GD biblioteca, e manter gif animação

Você precisa decompor o gif para frames, miniatura e re-montar.

Tenha um olhar em ImageMagick e neste tutorial .

O exemplo http://www.php.net/manual/en /imagick.coalesceimages.php irá redimensionar seu gif, mantendo a sua estrutura timing. Algo que a maioria dos outros exemplos não fazer.

Outros exemplos reconstruir o gif enquanto este permite que você Modificar os quadros da imagem.

Eu tentei inúmeros exemplos de redimensionamento GIFs animados com o módulo Imagick PHP, mas nenhum deles funcionou para mim. Então, depois de algum tempo de depuração, finalmente eu encontrei o problema real: a animação foi perdida ao salvar imagem em disco, por $animation->writeImage($file_dst); ou $animation->writeImages($file_dst, true);

Eu mudei-o para file_put_contents($file_dst, $animation->getImagesBlob()); e a maioria dos exemplos começou a trabalhar imediatamente.

Espero que ajude alguém.

Se você tem ImageMagick instalado, então você pode usar uma única chamada para convert:

system("convert big.gif -coalesce -repage 0x0 -resize 200x100 -layers Optimize small.gif");

Eu acho que eu tenho isso no saco.

Esta solução não é de forma perfeita e contém alguma força bruta aqui e ali, mas eu era capaz de acrescentar minha GD / PHP redimensionamento roteiro imagem baseada com a funcionalidade suficiente para animações de apoio.

A solução é fortemente baseado nos excelentes bibliotecas de freeware por László Zsidi - http: // www.phpclasses.org/browse/author/283569.html

Você pode conferir uma demonstração rápida e descarregue as fontes de http://forssto.com/gifexample/ (link direto: http://forssto.com/gifexample/gifanimresize.zip )

Problemas conhecidos:

  • Suporte

    Transparência - esta seria fácil de acrescentar a esta solução, mas como eu não tenho uma necessidade imediata de isso, eu vou parar aqui.

  • Taxa de quadros - por alguma razão desconhecida a classe GifEncoder não tomar em conta as taxas de quadros Especificadas. Vou precisar de olhar para isso mais tarde.

  • Eu achei um arquivo GIF do meu set de testes que de alguma forma teve diferentes quadros de tamanho na mesma e que a animação falhou ao trabalho corretamente. ainda alguns depuração para fazer então.

apenas creat 3 pasta 2.images nome 1.frame_output 3.resized_frame_output e descarga 2 codificador e decodificador de classe a partir deste link abaixo classe 1.Download "GIFDecoder.class.php" do http: //phpclasses.elib. com / browse / pacote / 3234.html classe 2.Download "GIFEncoder.class.php" do http: //phpclasses.betablue. net / browse / pacote / 3163.html

e, em seguida, executar o nome do script como "resize_animator.php", creat um arquivo de upload html & Let Aproveite o script.

.. Salvar este script como ..... index.php .......

<html>
<body>
<table width="500" border="0" align="center" cellpadding="0" cellspacing="1" bgcolor="#CCCCCC">
<tr>
<form action="resize_animator.php" method="post" enctype="multipart/form-data" >
<td>
<table width="100%" border="0" cellpadding="3" cellspacing="1" bgcolor="#FFFFFF">
<tr>
<td align="center"><font face="Tahoma">SELECT ANIMATED FILE</font> 
<input type="file" name="uploadfile" size="20" accept="image/gif"/>
</td>
</tr>
<tr>
<td align="center"><input type="submit" name="Submit" value="PROCESS ANIMATION" /></td>
</tr>
</table>
</td>
</form>
</tr>
</table>
</body>
</html>

........................ salvar e este script como resize_animator.php ............

   <?php

   require "GIFDecoder.class.php";
   include "GIFEncoder.class.php";
   $file_name= $_FILES['uploadfile']['name'];
   $file_ext = substr($file_name, -4);
   $file_size=($_FILES["uploadfile"]["size"] /1024 );
   if($file_ext=='.gif')
    {
 if($file_size > 0 && $file_size < 2000 )
  {
    session_start ( );
        $uploaded_file = $_FILES['uploadfile']['tmp_name'];
        $fp=file_get_contents($uploaded_file);

        if ( $fp )
            {
                $_SESSION['delays'] = Array ( );
                $gif = new GIFDecoder ( $fp );
                $arr = $gif->GIFGetFrames ( );
                $_SESSION [ 'delays' ] = $gif -> GIFGetDelays ( );

                for ( $i = 0; $i < count ( $arr ); $i++ )
                {
                        fwrite ( fopen ( ( $i < 10 ? "frame_output/$i$i_frame.gif" : "frame_output/$i_frame.gif" ), "wb" ), $arr [ $i ] );
                }
          }

        function resize_frames($newwidth,$newheight)
            {
                    $dir=opendir("frame_output/");
                    $i=0;
                    while($imgfile=readdir($dir))
                    {
                         if ($imgfile != "." && $imgfile!="..")
                             {
                                        $imgarray[$i]=$imgfile;
                                        $uploadedfile = "frame_output/".$imgarray[$i];
                                        $src = imagecreatefromgif($uploadedfile);
                                        list($width,$height)=getimagesize($uploadedfile);
                                        $tmp=imagecreatetruecolor($newwidth,$newheight);
                                        imagecopyresampled($tmp,$src,0,0,0,0,$newwidth,$newheight,$width,$height);
                                        $filename = "resized_frame_output/".$imgarray[$i];
                                        imagegif($tmp,$filename,100);
                                        imagedestroy($src);
                                        imagedestroy($tmp);
                                        $i++;
                            }
                    }
                    closedir($dir);

                if ( $dh = opendir ( "resized_frame_output/" ) )
                {
                    while ( false !== ( $dat = readdir ( $dh ) ) )
                    {
                        if ( $dat != "." && $dat != ".." )
                        {
                            $frames [ ] = "resized_frame_output/$dat";
                        }
                    }
                    closedir ( $dh );
                }

            $gif = new GIFEncoder   ( $frames,$_SESSION [ 'delays' ],0, 2, 0, 0, 0,"url" );
            $data = $gif->GetAnimation ( );

            $x='x';
            $y='_';
            $uploaded_file_name= $_FILES['uploadfile']['name'];
            $actual_file_name = substr($uploaded_file_name, 0, -4);
            $file_extention = substr($uploaded_file_name, -4);
            $new_name=$actual_file_name.$y.$newwidth.$x.$newheight.$file_extention ;

            //$output_image_name=$newwidth.$x.$newheight;
            fwrite ( fopen ( "images/$new_name", "wb" ), $data );
            //remove resized frames from folder
            //sleep for 1 second
            // usleep(2000000);
            $dir = 'resized_frame_output/';
            foreach(glob($dir.'*.*') as $v)
                {
                 unlink($v);
                }
        }  // end of function resize_frames


            $gif = new GIFEncoder   ( $frames,$_SESSION [ 'delays' ],0, 2, 0, 0, 0,"url" );
            $data = $gif->GetAnimation ( );

            $x='x';
            $y='_';
            $z='_p';
            $uploaded_file_name= $_FILES['uploadfile']['name'];
            $actual_file_name = substr($uploaded_file_name, 0, -4);
            $file_extention = substr($uploaded_file_name, -4);
            $new_name=$actual_file_name.$y.$newwidth.$x.$newheight.$z.$file_extention ;

            //$output_image_name=$newwidth.$x.$newheight;
            fwrite ( fopen ( "images/$new_name", "wb" ), $data );
            //remove resized frames from folder
            //sleep for 1 second
             //usleep(2000000);
            $dir = 'resized_frame_output/';
            foreach(glob($dir.'*.*') as $v)
                {
                 unlink($v);
                }
        }  // end of function resize_frames

            resize_frames(110,110);
            resize_frames(120,160);
            resize_frames(120,80);
            resize_frames(128,96);
            resize_frames(128,128);
            resize_frames(208,208);
            resize_frames(208,320);

            session_destroy();

            //usleep(200000);

            //remove resized frames from folder
            $dir = 'frame_output/';
            foreach(glob($dir.'*.*') as $v)
                {
                 unlink($v);
                }
      echo "<center><h1>Your Animation processing is compleated.</h1></center>";
      echo "<center><h2><a href=\"index.php\">BACK TO UPLOAD PAGE</h2></center>";
  }  //end of file size checker
else
 {
      echo "<center><h2>You Upload a unfit size image .Upload a file within 2000 KB</h2></center>";
      echo "<center><h2><a href=\"index.php\">BACK TO UPLOAD PAGE</h2></center>";
 }
   } //end of file extention checker
  else
  {
   echo "<center><h2>Uplaod a gif file!</h2></center>";
   echo "<center><h2><a href=\"index.php\">BACK TO UPLOAD PAGE</h2></center>";
  }
  ?>

....................... Permite desfrutar ............

uncomment a função usleep para ver o trabalho acontecer naqueles folders.its não é necessário, mas eu usá-lo para ver a funcionalidade.

Se você não tem Imagemagick em seu servidor, você pode querer tentar o seguinte:

http: //www.phpclasses.org/package/7353-PHP-Resize-animations-in-files-of-the-GIF-format.html

A classe é o redimensionamento animações GIF com GD. Primeiro analisa os quadros, em seguida, redimensiona-los, depois que ele compila-los novamente em único arquivo sem perder seus tempos de atraso, os métodos de eliminação, tabelas de cores etc.

Tente e se você encontrar um bug ou quiser sugerir algumas otimizações etc, você pode usar o fórum de classe ou deixe um comentário na página em meu site. E eu vou responder a isso o mais rápido possível.

Este todas as respostas, exceto através ImageMagick não funcionou para mim. Scripts em respostas antes disso são todos cheios de erros.

Mesmo instalar ImageMagick era difícil de gerir isso aqui é a minha experiência.

Aqui está como instalar ImageMagick em janelas 7 e xampp 1.7.4.
Nota :. Escolha 64 bits (para win7), e quando a licença instalando marcada a opção "Adicionar a caminho do sistema"

E, em seguida, seguir: http://www.creativearmory.com/tutorials/resize -animated-gifs-com-php-and-imagemagick

Eu tenho horas perdido em scripts em mensagens deste, e ImageMagick e este tutorial foi sucessfull em minutos.

E mais uma nota:. Meu servidor tem ImageMagick por padrão, então eu acho que a maioria dos servidores têm também

GIF Animação Resizer é uma ferramenta de uma classe simples que irá fazer o truque.

Nota: Ele usa uma pasta temporária para escrever os quadros separados. Embora timestamps os quadros, você pode precisar criar uma pasta única, se você pretende usar isso em um servidor onde vários usuários será redimensionamento GIFs ao mesmo tempo.

Imagecraft é uma biblioteca PHP GD confiável e extensão que mantém animação GIF, editar e imagens compor em múltiplas camadas e suportes marca d'água.

Eu usei esta função:

function gifResize($file_origin,$file_dest,$percent){       
   $crop_w = 0;
   $crop_h = 0;
   $crop_x = 0;
   $crop_y = 0;
   $image = new Imagick($file_origin);
   $originalWidth = $image->getImageWidth();
   $originalHeight = $image->getImageHeight();
   $size_w = ($originalWidth*$percent)/100;
   $size_h = ($originalHeight*$percent)/100;
   if(($size_w-$originalWidth)>($size_h-$originalHeight)){
       $s = $size_h/$originalHeight;
       $size_w = round($originalWidth*$s);
       $size_h = round($originalHeight*$s);
   }else{
       $s = $size_w/$originalWidth;
       $size_w = round($originalWidth*$s);
       $size_h = round($originalHeight*$s);
   }       
   $image = $image->coalesceImages();

   foreach ($image as $frame) {
       $frame->cropImage($crop_w, $crop_h, $crop_x, $crop_y);
       $frame->thumbnailImage($size_h, $size_w);
       $frame->setImagePage($size_h, $size_w, 0, 0);
   }
   $imageContent = $image->getImagesBlob();
   $fp = fopen($file_dest,'w');
   fwrite($fp,$imageContent);
   fclose($fp);

}

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top