Redimensione o arquivo GIF animado sem destruir a animação

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

Como posso fazê-lo usando o PHP?

Se você tiver o access imagemagick, você pode fazer isso:

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

Isto é provavelmente possível com o plugin do imagemagick se você não tiver access ao sistema ()

NOTA: isso pode criar um tamanho maior de arquivos, embora uma imagem de dimensões menores devido ao coalescimento essencialmente desoptimizando a imagem.

UPDATE: se você não tiver access ImageMagick, você poderá usar uma combinação das seguintes etapas para resize um gif animado (assumindo que você tenha access GD):

  1. Detecta se a imagem é um gif animado: Posso detectar gifs animados usando php e gd? (resposta principal)
  2. Divida o gif animado em frameworks individuais: http://www.phpclasss.org/package/3234-PHP-Split-GIF-animations-to-multiple-images.html
  3. Redimensionar os frameworks individuais: http://www.akemapa.com/2008/07/10/php-gd-resize-transparent-image-png-gif/
  4. Recompense os frameworks em um gif animado novamente: http://www.phpclasss.org/package/3163-PHP-Generate-GIF-animations-from-a-set-of-GIF-images.html

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

Se você conseguir funcionar, por favor, compartilhe com o mundo!

Experimente GDEnhancer (Use ImageCraft ). Só precisa da biblioteca GD, e mantém a animação gif

Você precisaria decompor o gif em frameworks, miniaturas e voltar a montar.
Dê uma olhada no ImageMagick: http://php.net/imagick e este tutorial: http://www.phpro.org/examples/Thumbnail-From-Animated-GIF.html

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

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

Espero que ajude alguém.

O exemplo em http://www.php.net/manual/en/imagick.coalesceimages.php irá resize o seu gif enquanto mantém o tempo da moldura. Algo da maioria dos outros exemplos não faz.

Outros exemplos reconstruem o gif enquanto este permite que você modifique os frameworks da imagem.

Se você tiver o ImageMagick instalado, 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 na bolsa.

Esta solução não é perfeita e contém alguma força bruta aqui e ali, mas eu consegui acrescentar meu script de redimensionamento de imagem baseado em GD / PHP com funcionalidade suficiente para suportar animações.

A solução está fortemente baseada nas excelentes bibliotecas de freeware de László Zsidi – http://www.phpclasss.org/browse/author/283569.html

Você pode verificar uma demonstração rápida e baixar as fonts em http://forssto.com/gifexample/ (link direto: http://forssto.com/gifexample/gifanimresize.zip )

QUESTÕES CONHECIDAS:

  • Suporte de transparência – isso seria fácil de acrescentar a esta solução, mas como não tenho necessidade imediata disso, vou parar aqui.

  • Taxa de frameworks – por algum motivo desconhecido, a class GIFEncoder não leva em consideração as taxas de frameworks especificadas. Preciso examinar isso mais tarde.

  • Encontrei um arquivo gif do meu conjunto de testes que, de alguma forma, tinham molduras de tamanho diferente e que a animação não funcionava corretamente. Ainda há alguma debugging para fazer então.

apenas o nome da pasta creat 3 1.frame_output 2.images 3.resized_frame_output e baixe 2 codificador e decodificador a partir deste link abaixo 1.Download class “GIFDecoder.class.php” em http://phpclasss.elib.com/browse/package /3234.html 2.Download class “GIFEncoder.class.php” de http://phpclasss.betablue.net/browse/package/3163.html

e então execute o nome do script como “resize_animator.php”, crie um arquivo html de upload e deixe aproveitar o script.

.. salve esse script como ….. index.php …….

   
SELECT ANIMATED FILE

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

   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 "

Your Animation processing is compleated.

"; echo "

BACK TO UPLOAD PAGE

"; } //end of file size checker else { echo "

You Upload a unfit size image .Upload a file within 2000 KB

"; echo "

BACK TO UPLOAD PAGE

"; } } //end of file extention checker else { echo "

Uplaod a gif file!

"; echo "

BACK TO UPLOAD PAGE

"; } ?>

…………………..VAMOS APROVEITAR…………

Descomente a function usleep para ver o trabalho acontecer nessas pastas. Não é necessário, mas eu uso isso para ver a funcionalidade.

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

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

A class está redimensionando animações GIF com GD. Primeiro analisa os frameworks, depois redimensiona-os, depois disso os compila novamente em um único arquivo sem perder seus tempos de atraso, methods de eliminação, tabelas de colors etc.

Experimente e se você encontrar um bug ou quiser sugerir algumas otimizações etc., você pode usar o fórum da class ou deixar um comentário na página no meu site. E responderei o mais rápido possível.

Todas essas respostas, exceto pelo ImageMagick, não funcionaram para mim. Scripts nas respostas antes disso estão cheios de erros.

Mesmo a instalação do ImageMagick foi difícil de gerenciar, então aqui está minha experiência.

Veja como instalar o ImageMagick no Windows 7 e o xampp 1.7.4.
Nota : Escolha 64 bit (para win7) e, ao instalar a licença, verificou a opção “Adicionar ao caminho do sistema”.

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

Perdi horas em scripts nestas postagens, e ImageMagick e este tutorial foram bem sucedidos em minutos.

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

GIF Animation Resizer é uma ferramenta simples de uma class que fará o truque.

Nota: ele usa uma pasta temporária para escrever os frameworks separados. Enquanto ele marca os frameworks, você precisará criar uma pasta única se você pretende usar isso em um servidor onde vários usuários resizeão GIFs ao mesmo tempo.

Imagecraft é uma biblioteca PHP GD confiável e uma extensão que mantém a animação GIF, edita e compõe imagens em várias camadas e suporta marca d’água.

Eu usei essa function:

 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); 

}

Intereting Posts