php - reducir - Cambiar el tamaño del archivo GIF animado sin destruir la animación
que tamaño debe tener un gif (13)
Creo que tengo esto en la bolsa.
Esta solución de ninguna manera es perfecta y contiene algo de fuerza bruta aquí y allá, pero pude agregar mi script de cambio de tamaño basado en GD / PHP con suficiente funcionalidad para admitir animaciones.
La solución se basa en gran medida en las excelentes librerías gratuitas de László Zsidi - http://www.phpclasses.org/browse/author/283569.html
Puede consultar una demostración rápida y descargar las fuentes de forssto.com/gifexample (enlace directo: http://forssto.com/gifexample/gifanimresize.zip )
PROBLEMAS CONOCIDOS:
Compatibilidad con la transparencia: esto sería fácil de agregar a esta solución, pero como no tengo una necesidad inmediata para esto, me estoy deteniendo aquí.
Velocidad de fotogramas: por algún motivo desconocido, la clase GifEncoder no tiene en cuenta las velocidades de fotogramas especificadas. Tendré que investigar esto más tarde.
Encontré un archivo gif de mi conjunto de pruebas que de alguna manera tenía marcos de diferentes tamaños y que la animación no funcionaba correctamente. Todavía hay algo de depuración que hacer entonces.
Necesito cambiar el tamaño de un archivo GIF animado sin destruir la animación.
¿Cómo puedo hacerlo usando PHP?
El ejemplo en http://www.php.net/manual/en/imagick.coalesceimages.php cambiará el tamaño de tu gif mientras conservas el tiempo de tu fotograma. Algo que la mayoría de los otros ejemplos no hacen.
Otros ejemplos reconstruyen el gif mientras este le permite modificar los marcos de la imagen.
He intentado numerosos ejemplos de cambiar el tamaño de GIF animados con el módulo Imagick PHP, pero ninguno de ellos funcionó para mí. Luego, después de un tiempo de depuración, finalmente encontré el problema real: la animación se perdió al guardar la imagen en el disco, por $animation->writeImage($file_dst);
o $animation->writeImages($file_dst, true);
Lo he cambiado a file_put_contents($file_dst, $animation->getImagesBlob());
y la mayoría de los ejemplos comenzaron a funcionar de inmediato.
Espero que ayude a alguien.
Pruebe GDEnhancer (use ImageCraft ). Solo necesita la Biblioteca de GD y mantiene la animación de GIF
Si no tiene Imagemagick en su servidor, puede intentar esto:
http://www.phpclasses.org/package/7353-PHP-Resize-animations-in-files-of-the-GIF-format.html
La clase está cambiando el tamaño de las animaciones GIF con GD. Primero analiza los cuadros, luego los redimensiona, luego los vuelve a compilar en un solo archivo sin perder sus tiempos de demora, métodos de eliminación, tablas de colores, etc.
Pruébalo y si encuentras un error o quieres sugerir algunas optimizaciones, etc. puedes usar el foro de la clase o dejar un comentario en la página de mi sitio web. Y lo responderé lo antes posible.
Si tiene ImageMagick instalado, puede usar una sola llamada para convert
:
system("convert big.gif -coalesce -repage 0x0 -resize 200x100 -layers Optimize small.gif");
Tendría que descomponer el gif en marcos, miniaturas y volver a armarlo.
Eche un vistazo a ImageMagick: http://php.net/imagick y este tutorial: http://www.phpro.org/examples/Thumbnail-From-Animated-GIF.html
Todas estas respuestas excepto a través de ImageMagick no funcionaron para mí. Los scripts en las respuestas anteriores están llenos de errores.
Incluso la instalación de ImageMagick fue difícil de administrar, así que aquí está mi experiencia.
Aquí se explica cómo instalar ImageMagick en windows 7 y xampp 1.7.4.
Nota : Elija 64 bit (para win7), y cuando instale deja marcada la opción "Agregar a la ruta del sistema".
Y luego siga: http://www.creativearmory.com/tutorials/resize-animated-gifs-with-php-and-imagemagick
He perdido horas en guiones en estas publicaciones, y ImageMagick y este tutorial han sido exitosos en minutos.
Y una nota más: mi servidor web tiene ImageMagick por defecto, así que supongo que la mayoría de los servidores también lo tienen.
Usé esta función:
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);
}
si tiene acceso a Imagemagick, puede hacer esto:
system("convert big.gif -coalesce coalesce.gif");
system("convert -size 200x100 coalesce.gif -resize 200x10 small.gif");
esto es muy posible con el plugin imagemagick si no tiene acceso al sistema ()
NOTA: esto puede crear un tamaño de archivo más grande a través de una imagen de dimensiones más pequeñas debido a la coalescencia que esencialmente desoptimiza la imagen.
ACTUALIZACIÓN: si no tiene acceso a ImageMagick, debería poder usar una combinación de los siguientes pasos para cambiar el tamaño de un gif animado (suponiendo que tenga acceso GD):
- Detecta si la imagen es un gif animado: ¿Puedo detectar gifs animados usando php y gd? (respuesta superior)
- Divida el gif animado en marcos individuales: http://www.phpclasses.org/package/3234-PHP-Split-GIF-animations-into-multiple-images.html
- Cambiar el tamaño de los marcos individuales: http://www.akemapa.com/2008/07/10/php-gd-resize-transparent-image-png-gif/
- Recompone los marcos en un gif animado de nuevo: http://www.phpclasses.org/package/3163-PHP-Generate-GIF-animations-from-a-set-of-GIF-images.html
Esto es definitivamente mucho más intensivo que la ruta de ImageMagick, pero debería ser técnicamente posible.
Si lo haces funcionar, ¡por favor comparte con el mundo!
simplemente crea 3 nombre de carpeta 1.frame_output 2.images 3.resized_frame_output y descarga 2 codificadores y clase de decodificador desde este enlace a continuación 1.Descarga la clase "GIFDecoder.class.php" desde http://phpclasses.elib.com/browse/package/3234.html 2.Descargue la clase "GIFEncoder.class.php" de http://phpclasses.betablue.net/browse/package/3163.html
y luego ejecute el nombre del script como "resize_animator.php", cree un archivo html y deje disfrutar el script.
..save 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>
........................ guarde y 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>";
}
?>
.......................DISFRUTEMOS............
elimine el comentario de la función usleep para ver el trabajo en esas carpetas. No es necesario, pero lo uso para ver la funcionalidad.
http://www.phpclasses.org/package/7353-PHP-Resize-animations-in-files-of-the-GIF-format.html es una herramienta simple de una sola clase que hará el truco.
Nota: Utiliza una carpeta temporal para escribir los marcos separados. Si bien marca el tiempo de los marcos, es posible que deba crear una carpeta única si tiene la intención de usar esto en un servidor donde varios usuarios cambiarán el tamaño de GIF al mismo tiempo.
ImageCraft es una biblioteca PHP GD confiable y una extensión que mantiene la animación GIF, edita y compone imágenes en múltiples capas y admite marcas de agua.