imagecreatefromgif

(PHP 4, PHP 5, PHP 7, PHP 8)

imagecreatefromgifCria uma nova imagem a partir de um arquivo ou URL

Descrição

imagecreatefromgif(string $filename): GdImage|false

imagecreatefromgif() retorna um identificador de imagem representando a imagem obtida a partir do arquivo informado.

Cuidado

Ao carregar arquivos GIF na memória, apenas o primeiro quadro é retornado ao objeto da imagem. O tamanho da imagem não é necessariamente o reportado por getimagesize().

Dica

Uma URL pode ser usada como um nome de arquivo com esta função se os empacotadores fopen estiverem habilitados. Consulte a função fopen() para mais detalhes sobre como especificar o nome do arquivo. Consulte os Protocolos e empacotadores suportados para obter links para informações sobre as capacidades de cada empacotador, notas de uso e informações sobre quaisquer variáveis predefinidas que eles possam fornecer.

Parâmetros

filename

Caminho para a imagem GIF.

Valor Retornado

Retorna um objeto de imagem em caso de sucesso, false em caso de erros.

Registro de Alterações

Versão Descrição
8.0.0 Em caso de sucesso, esta função agora retorna um objeto GDImage; anteriormente, um resource era retornado.

Exemplos

Exemplo #1 Exemplo de gerenciamento de erro durante carregamento de um GIF

<?php
function LoadGif($imgname)
{
/* Tenta abrir */
$im = @imagecreatefromgif($imgname);

/* Ver se falhou */
if(!$im)
{
/* Cria uma imagem vazia */
$im = imagecreatetruecolor (150, 30);
$bgc = imagecolorallocate ($im, 255, 255, 255);
$tc = imagecolorallocate ($im, 0, 0, 0);

imagefilledrectangle ($im, 0, 0, 150, 30, $bgc);

/* Mostra uma mensagem de erro */
imagestring ($im, 1, 5, 5, 'Error loading ' . $imgname, $tc);
}

return
$im;
}

header('Content-Type: image/gif');

$img = LoadGif('bogus.image');

imagegif($img);
?>

O exemplo acima produzirá algo semelhante a:

Saída do exemplo: Exemplo de gerenciamento de erro durante carregamento de um GIF
adicione uma nota

Notas Enviadas por Usuários (em inglês) 20 notes

up
15
frank at huddler dot com
13 years ago
An updated is_ani based on issues reported here and elsewhere

<?php
function is_ani($filename) {
if(!(
$fh = @fopen($filename, 'rb')))
return
false;
$count = 0;
//an animated gif contains multiple "frames", with each frame having a
//header made up of:
// * a static 4-byte sequence (\x00\x21\xF9\x04)
// * 4 variable bytes
// * a static 2-byte sequence (\x00\x2C) (some variants may use \x00\x21 ?)

// We read through the file til we reach the end of the file, or we've found
// at least 2 frame headers
while(!feof($fh) && $count < 2) {
$chunk = fread($fh, 1024 * 100); //read 100kb at a time
$count += preg_match_all('#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s', $chunk, $matches);
}

fclose($fh);
return
$count > 1;
}
?>
up
2
moxley at moxleydata dot com
18 years ago
I wanted to find out if a GIF is Black & White or Color, but I didn't want to wait around for imagecreatefromgif() to parse a 200k file (about 1 second) to get the color map, so I wrote this function to get a list of all the colors in the GIF. Hope it is useful for you.

<?php
function getGIFColorMap($file)
{
$fp = fopen($file, 'r');
$buf = fread($fp, 1024);
fclose($fp);

// Calculate number of colors
// buf[10] is the color info byte
$color_byte = ord($buf[10]);
$has_color_map = ($color_byte >> 7) & 1;
$color_res = (($color_byte >> 4) & 7) + 1;
$bits_per_pixel = ($color_byte & 7) + 1;
$color_count = 1 << $bits_per_pixel;

if (!
$has_color_map) return null;

// buf[13] is the beginning of the color map
$color_map_index = 13;
$map = array();
for (
$i=0; $i < $color_count; $i++) {
$index = $color_map_index + $i*3;
$r = ord($buf[$index]);
$g = ord($buf[$index + 1]);
$b = ord($buf[$index + 2]);
$map[$i] = array($r, $g, $b);
}
return
$map;
}
?>
up
2
hdogan at gmail dot com
8 years ago
Just realised that some of the animated GIFs do not contain GCE (graphic control extension). Here is the refactored is_ani() function:

<?php
/**
* Detects animated GIF from given file pointer resource or filename.
*
* @param resource|string $file File pointer resource or filename
* @return bool
*/
function is_animated_gif($file)
{
$fp = null;

if (
is_string($file)) {
$fp = fopen($file, "rb");
} else {
$fp = $file;

/* Make sure that we are at the beginning of the file */
fseek($fp, 0);
}

if (
fread($fp, 3) !== "GIF") {
fclose($fp);

return
false;
}

$frames = 0;

while (!
feof($fp) && $frames < 2) {
if (
fread($fp, 1) === "\x00") {
/* Some of the animated GIFs do not contain graphic control extension (starts with 21 f9) */
if (fread($fp, 1) === "\x21" || fread($fp, 2) === "\x21\xf9") {
$frames++;
}
}
}

fclose($fp);

return
$frames > 1;
}
up
2
ZeBadger
12 years ago
The version of is_ani that reads the file in 100Kb chunks is flawed as the end of frame marker might be split in between 2 chunks - so be careful.
up
1
josh [ a t ] OnlineComics [ d o t ] net
21 years ago
I just installed gif2png on my server, and it took a little research on my part to figure out that this...

passthru("$path/gif2png -O $image_path/image.gif")

will not work if safe mode is on. If you're on a shared server, it probably is. You don't need to turn safe mode off, however, just set the safe_mode_exec_dir variable in your php.ini file to the directory where you installed gif2png. Then you'll be able to execute the program from your PHP script.
up
1
unknown at hotmail dot com
22 years ago
If GD doesn't support GIFs & gif2png is not available & you are not an administrator, you can install it in your account like this:

create do.php:
<?
global $do;
passthru($do);
?>

then upload gif2png-2.4.6.tar.gz, unpack and install it:
do.php?do=tar+-xvzf+gif2png-2.4.6.tar.gz
do.php?do=gif2png-2.4.5/configure
do.php?do=make

Then remove all files except gif2png. Don't forget to remove do.php as it is a serious security hole in your system.

Njoy!

Anze
up
4
ZeBadger
19 years ago
I have written this code to detect if a gif file is animated or not. I thought I would share it :-)

<?php

function is_ani($filename)
{
$filecontents=file_get_contents($filename);

$str_loc=0;
$count=0;
while (
$count < 2) # There is no point in continuing after we find a 2nd frame
{

$where1=strpos($filecontents,"\x00\x21\xF9\x04",$str_loc);
if (
$where1 === FALSE)
{
break;
}
else
{
$str_loc=$where1+1;
$where2=strpos($filecontents,"\x00\x2C",$str_loc);
if (
$where2 === FALSE)
{
break;
}
else
{
if (
$where1+8 == $where2)
{
$count++;
}
$str_loc=$where2+1;
}
}
}

if (
$count > 1)
{
return(
true);

}
else
{
return(
false);
}
}

exec("ls *gif" ,$allfiles);
foreach (
$allfiles as $thisfile)
{
if (
is_ani($thisfile))
{
echo
"$thisfile is animated<BR>\n";
}
else
{
echo
"$thisfile is NOT animated<BR>\n";
}
}
?>

It could quite easily be modified to count the number of frames if you required.
up
1
marianbucur17 at yahoo dot com
8 years ago
I hate created an improved version of frank at huddler dot com's is_ani function, which keeps score even between hunks. Hope this helps!

/**
* Check if the provided file is an animated gif.
*
* @param string $fileName
* @return bool
*/
function isAnimatedGif($fileName)
{
$fh = fopen($fileName, 'rb');

if (!$fh) {
return false;
}

$totalCount = 0;
$chunk = '';

// An animated gif contains multiple "frames", with each frame having a header made up of:
// * a static 4-byte sequence (\x00\x21\xF9\x04)
// * 4 variable bytes
// * a static 2-byte sequence (\x00\x2C) (some variants may use \x00\x21 ?)

// We read through the file until we reach the end of it, or we've found at least 2 frame headers.
while (!feof($fh) && $totalCount < 2) {
// Read 100kb at a time and append it to the remaining chunk.
$chunk .= fread($fh, 1024 * 100);
$count = preg_match_all('#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s', $chunk, $matches);
$totalCount += $count;

// Execute this block only if we found at least one match,
// and if we did not reach the maximum number of matches needed.
if ($count > 0 && $totalCount < 2) {
// Get the last full expression match.
$lastMatch = end($matches[0]);
// Get the string after the last match.
$end = strrpos($chunk, $lastMatch) + strlen($lastMatch);
$chunk = substr($chunk, $end);
}
}

fclose($fh);

return $totalCount > 1;
}
up
0
simon at shortpixel dot com
7 years ago
A fix for the problem of the current is_ani function is to add the last 20b of the previous frame to the next one:

<?php
function is_ani($filename) {
if(!(
$fh = @fopen($filename, 'rb')))
return
false;
$count = 0;
//an animated gif contains multiple "frames", with each frame having a
//header made up of:
// * a static 4-byte sequence (\x00\x21\xF9\x04)
// * 4 variable bytes
// * a static 2-byte sequence (\x00\x2C) (some variants may use \x00\x21 ?)

// We read through the file til we reach the end of the file, or we've found
// at least 2 frame headers
$chunk = false;
while(!
feof($fh) && $count < 2) {
//add the last 20 characters from the previous string, to make sure the searched pattern is not split.
$chunk = ($chunk ? substr($chunk, -20) : "") . fread($fh, 1024 * 100); //read 100kb at a time
$count += preg_match_all('#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s', $chunk, $matches);
}

fclose($fh);
return
$count > 1;
}
?>