Portál o technologiích a vývoji

Obrázky ve webových aplikacích – Animované GIFy

Autor: Adam Klvač Datum: 26.9.2013 Počet shlédnutí: 3 961 169x

Miluji zábavné animované GIFy. Narozdíl od zábavných videí do nich autoři nemůžou dát svou oblíbenou písničku, nedávají do nich intro a titulky (zatím) a nemusíte se obtěžovat tím, abyste si „video“ spustili znova. Pokud budete vyvíjet galerii, neberte GIFům pohyb.

Při jakékoliv manipulaci s animovaným GIFem bohužel dojde k tomu, že už nebude animovaný. Jde vlastně o vícevrstvý obrázek a je nutné s ním podle toho nakládat. Dá se to vyřešit dvěmi způsoby – první je použití programu convert v Linuxu, kterému pošleme argumenty skrze funkci system. To ale téměř nikde není reálné, protože snad všechny hostingy to z pochopitelných důvodů blokují. Proto je nutné jít druhou metodou – rozdělit GIF na jednotlivé obrázky, zpracovat je (tzn. otočit, zmenšit, vložit vodoznak) a složit zpátky na GIF.

Prvním krokem je detekce, zda je obrázek animovaný GIF. Tuto funkci jsem našel v komentářích dokumentace PHP.

/**
 * Ověří, zda je obrázek animovaný.
 * @url http://it.php.net/manual/en/function.imagecreatefromgif.php#59787
 */
function is_animated($filename) {

    $filecontents=file_get_contents($filename);
    $str_loc=0;
    $count=0;
    while($count < 2) {
        $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;
            }
        }
    }

    return $count > 1;

}

Dalším krokem je rozdělení snímků GIFu na jednotlivé obrázky, úprava a následné sloučení. Lze toho docílit třeba pomocí knihovny gifsplit a gifmerge.

// Vytvoření instance GIFDecoderu (přijímá název GIFu a jeho velikost)
$decoder = new GIFDecoder(file_get_contents(
    $_FILES['soubor']['tmp_name']), $_FILES['soubor']['size']
);

// Pole na zpracované snímky a jednotlivé časy prodlev mezi nimi
$frames = array();
$delays = array();

// Projdeme postupně všechny snímky
foreach($decoder->GIFGetFrames() as $frame) {

    // Zpracování jako běžný obrázek
    $image = imagecreatefromstring($frame);

    // Necháme vypsat obrázek a zachytíme jeho data do řetězce
    ob_start();
    $frames[] = ob_get_clean();
    $delays[] = 5;

}

// Sloučíme obrázky zpět do GIFu (pole s daty obrázků, prodlevy)
$encoder = new GIFEncoder(
    $frames, $delays,
    0, 2, 0, 0, 0,
    'bin'
);

// Uložíme obrázek
file_put_contents($encoder->GetAnimation(), "název obrázku.gif");

Jde o relativně náročný proces, který může potřebovat docela dost paměti i času. Pokud si ale pohyblivé GIFy vůbec nepřejeme, můžeme použít alespoň první funkci k informování uživatele o tom, že animované GIFy nejsou povoleny.

Štítky: | | |

Žádné komentáře

Poslat komentář

Vaše e-mailová adresa nebude zveřejněna.