Yo'Sarin bloguje

Přeskočit navigaci

  • Všechny sekce
    (116 článků)
  • Fotogalerie
    (14 článků)
  • PC
    (15 článků)
  • Jen tak
    (58 článků)
  • Povídky
    (4 články)
  • O bloku
    (7 článků)
  • Škola
    (9 článků)
  • Hádanky
    (3 články)
  • Štafety
    (6 článků)
  • Přihlášení
  • Přepínač stylů

  • Ikonky v PHP

    15. 3. 2007, 21:35 napsal Yo'Sarin, sekce PC, přečteno 2236×, Linkuj si !

    Ukázková ikonka Ukázková ikonka číslo dva Ukázková ikonka číslo tři
    Jednoduchý a navíc i celkem krátký návod na tvorbu takovýchto grafických ikonek pomocí php.

    Potřebné funkce

    Nejdřív se podíváme na funkce, které budeme pro tvoření ikonek potřebovat. Pokud ale chcete, můžete rovnou přejít k tvorbě ikonek.

    resource imagecreate(int x_size, int y_size); Tato funkce vytvoří obrázek o rozměrech x_size × y_size a vrátí jeho identifikátor (objekt typu resource) se kterým pracují ostatní funkce.

    int imagecolorallocate(resource image, int red, int green, int blue); Tahle funkce je trochu složitější. Vrací identifikátor vytvořené (naalokované) barvy. Co za barvu to bude určíte pomocí parametrů red, green a blue - úplně stejně jako například v CSS. Touto funkcí musíte naalokovat (strašné slovo) všechny barvy, které chcete v obrázku image použít. Při prvním volání této funkce je celý (dosud prázdný) obrázek image vyplněn zadanou barvou.

    int imagestring(resource image, int font, int x, int y, string s, int col); Do obrázku image vykreslí na souřadnice x a y text řetězce s. Barvu řetězce udá její identifikátor col (vytvořený pomocí imagecolorallocate).
    Parametr font určuje který typ fontu se má použít - zadává se jeho identifikátor. My budeme pracovat pouze s identifikátory 1-5, což jsou build-in fonty. Můžete také použít vlastní font, ale jen bitmapový. Ten nahrajete pomocí funkce imageloadfont, která vrací identifikátor nově nahraného fontu. Pro true-type fonty existuje speciální funkce imagettftext.

    int imagecopy(resource dst_im, resource src_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h); Z obrázku src_im "vyřízne" z pozice src_x, src_y obdélník o šířce src_w a výšce src_h a tento výřez vloží do obrázku dst_im na pozici dst_x, dst_y.

    bool imagegif(resource image [, string filename]); Funkce má jeden nepovinný parametr - filename. Pokud je zadán, tak se na serveru vytvoří soubor s odpovídajícím jménem a do něj se uloží samotný obrázek image ve formátu gif. Pokud je tenhle parametr vynechán, pošle se obrázek přímo na výstup (opět jako gif).

    int header(string string); Tahle funkce sama o sobě nemá s obrázky pranic společného - použijeme ji k tomu, abychom prohlížeči řekli, že soubor který mu posíláme je obrázek a ne textový soubor.

    Jednoduchý obrázek

    Tak, potřebné funkce bychom znali a můžeme zkusit udělat nějaký primitivní obrázek - třeba jednobarevný obdélník. A třeba takovýhle: fialovy obdélníček <?php
    $obrazek = imagecreate(80, 15);
    //vytvořím si obrázek o rozměrech 80x15 px

    $fialova = imagecolorallocate($obrazek, 0xff, 0x00, 0xff);
    /*   
    jde o první volání funkce imagecolorallocate na obrázek $obrazek
    proto se obrázek vybarví fialovou barvou. Fialovou proto, že jsem předal
    rgb kód ff00ff, ne proto, že jsem proměnnou pojmenoval $fialova ;)
    obrázek je teď už v podstatě hotový - stačí ho jen poslat "ven"
    */

    header("Content-type: image/gif");
    //říkám prohlížeči, aby se souborem zacházel jako s normálním obrázkem typu gif

    imagegif($obrazek);
    //posílám prohlížeči data obrázku
    ?>
    Tenhle kód si uložte třeba do souboru fialovyObdelnik.php a pro vložení do stránky použijte tag <img>, stejně jako pro normální obrázek. <img src="fialovyObdelnik.php" />

    Rámeček kolem obrázku

    V zásadě jsou dvě možnosti - buď do obrázku nakreslíme 4 úsečky tak, aby vznikl rámeček, nebo vytvoříme dva obrázky, z nichž jeden bude o dvojnásobek šířky rámečku vyšší a širší než ten druhý.
    Já vám ukážu druhé řešení - přijde mi méně pracné.
    Výsledek může vypadat třeba takhle: Obdélník s rámečkem <?php
    $ramecek = imagecreate(80, 17);
    $vnitrek = imagecreate(76, 13);
    //vytvořím si dva obrázky

    $barvaRamecku = imagecolorallocate($ramecek, 0x00, 0xDD, 0x00);
    $barvaVnitrku = imagecolorallocate($vnitrek, 0xff, 0x00, 0xff);
    //nastavím jejich barvu

    imagecopy($ramecek, $vnitrek, 2, 2, 0, 0, 76, 13);
    //a teď už jen zkopíruji výplň do rámečku na souřadnice 2, 2
    //vznikne tak 2px široký okraj vlevo a nahoře. Šířka pravého a
    //dolního okraje je dána rozdílem zbývající délky (resp. výšky)
    //rámečku a šířky (resp. výšky) vkládaného pozadí.
    //(to jest těch 76 a 13).

    header("Content-type: image/gif");
    imagegif($ramecek);
    ?>
    Ono je těch možností defacto víc - přinejmenším můžete výplňovému obrázku nastavit velikost pouze 1×1 pixel - on se ten jeden pixel čtvereční zvětší tolikrát aby vyplnil celou oblast zadanou při kopírování.

    Text v obrázku

    Použijeme funkci imagestring: Obdélník s rámečkem a textem <?php
    $ramecek = imagecreate(80, 17);
    $vnitrek = imagecreate(76, 13);
    //vytvořím si dva obrázky

    $barvaRamecku = imagecolorallocate($ramecek, 0x00, 0xDD, 0x00);
    $barvaVnitrku = imagecolorallocate($vnitrek, 0xff, 0x00, 0xff);
    //nastavím jejich barvu

    imagecopy($ramecek, $vnitrek, 2, 2, 0, 0, 76, 13);
    //nakopíruji je na sebe

    $barvaTextu = imagecolorallocate($ramecek, 0x00, 0x00, 0x00);
    //tady si naalokuji barvu, ktrou se napíše text - barvu alokuji vzhledem k tomu
    //obrázku do kterého chci psát.

    imagestring($ramecek, 4, 3, 0, "Nazdar", $barvaTextu);
    //do obrázku $ramecek vypisuji text "Nazdar".
    //Bude použit font s identifikátorem 4, což je jeden z pěti standartních fontů.
    //Pět základních fontů se od sebe liší především velikostí a "tučností", tvary písmen
    //jsou IMHO shodné.

    header("Content-type: image/gif");
    imagegif($ramecek);
    ?>

    K čemu to?

    Asi hlavním důvodem pro tvoření takovýchhle ikonek pomocí php je IMHO možnost variability - napíšete si jeden skript a pak ho můžete do stránky vložit třeba s nějakým parametrem, který ovlivní vzhled obrázku.
    <img src="/clanky/ikonky/obrazek_s_atributy.php?color=red" />
    <img src="/clanky/ikonky/obrazek_s_atributy.php?color=blue" />
    <img src="/clanky/ikonky/obrazek_s_atributy.php" />
    <?php
    $ramecek = imagecreate(80, 17);
    $vnitrek = imagecreate(76, 13);
    //vytvořím si dva obrázky

    $barvaRamecku = imagecolorallocate($ramecek, 0x00, 0xDD, 0x00);
    //nastavim barvu ramecku

    if($_GET["color"] == "red")
    $barvaVnitrku = imagecolorallocate($vnitrek, 0xFF, 0x00, 0x00);
    else if($_GET["color"] == "blue")
    $barvaVnitrku = imagecolorallocate($vnitrek, 0x00, 0x00, 0xFF);
    else
    $barvaVnitrku = imagecolorallocate($vnitrek, 0x00, 0x00, 0x00);
    //Zjistím jakou hodnotu má atribut "color" poslaný skriptu a podle toho nastavím barvu.
    //Pokud používáte skript s atributy, nezapomeňte podchytit všechny možné hodnoty.

    imagecopy($ramecek, $vnitrek, 2, 2, 0, 0, 76, 13);

    header("Content-type: image/gif");
    imagegif($ramecek);
    ?>

    Moje ikonky

    To jen čistě pro inspiraci - aby jste viděli, co všechno se v takovém skriptu dá použít. Pochopitelně to není dokonalé a sneslo by to ještě hodně dalších vychytávek, ale IMHO to stačí takhle. :-) <?php
    if(!strchr($_SERVER['HTTP_REFERER'], "http://blok.yosarin.net") || empty($_GET)){    $_GET = array();
    $_GET['1'] = "yosarin";
    $_GET['2'] = "bloguje";
    /*   
    kontroluju odkud někdo ty ikonky odkazuje - pokud to není z mého blogu, tak má dotyčný
    smůlu a místo textu který si přeje se mu na ikonku vypíše pouze že "yosarin bloguje".
    */
    }
    $k = 0;
    $delkaCelkem = 0;
    $obrazek = array();
    $delka = array();
    /*   
    tentokrát pracuji s poli místo s jednoduchými proměnnými. Je to proto, že celá
    ikonka se skládá z předem neurčeného množství polí (resp. to množství těch polí
    je určeno počtem vstupních parametrů)
    */
    foreach($_GET as $text){    //procházím každý parametr který byl skriptu předán
    $delka[$k] = strlen($text)*5 + 5;
    //počítám potřebnou délku segmentu, aby se do něj vešel text $text
    $delkaCelkem += $delka[$k];
    //$delkaCelkem mi řekne jak dlouhý budu potřebovat "nejspodnější" obrázek
    $obrazek[$k] = imagecreate($delka[$k], 12);
    if($k % 2 == 0){    $bckgColor = imagecolorallocate($obrazek[$k], 0xff, 0xff, 0xff);
    $textColor = imagecolorallocate($obrazek[$k], 0x00, 0x00, 0x00);
    }
    else{    $bckgColor = imagecolorallocate($obrazek[$k], 0x99, 0x99, 0xff);
    $textColor = imagecolorallocate($obrazek[$k], 0x00, 0x00, 0x00);
    }
    //zjišťuji, jestli je segment v pořadí na liché nebo sudé pozici a podle toho ho vybarvuji
    imagestring($obrazek[$k],1,3,2,strtoupper(urldecode($text)),$textColor);
    //do obrázku vepíšu text, který byl poslán v parametru.
    $k++;
    }
    $delkaCelkem += ($k - 1) + 4;

    $pozadi1 = imagecreate($delkaCelkem, 16);
    $pozadi1_color = imagecolorallocate($pozadi1,0x00, 0x00, 0x00);
    $pozadi2 = imagecreate($delkaCelkem - 2, 14);
    $pozadi2_color = imagecolorallocate($pozadi2,0x99,0x99,0xff);
    //rámeček je "dvouvrstvý" - vnější černá linka a z vnitřní strany světle modrá

    imagecopy($pozadi1,$pozadi2,1,1,0,0,$delkaCelkem - 2,14);
    //spojím obě dvě ohraničení do jednoho obrázku

    for($i = 0, $odsazeni = 2; $i < $k; $i++){    imagecopy($pozadi1, $obrazek[$i],$odsazeni,2,0,0,$delka[$i],12);
    $odsazeni += $delka[$i] + 1;
    //všechny segmenty nakopíruji do výsledného obrázku tak, aby byly oddělené 1px mezerou
    }

    header("Content-type: image/gif");
    imagegif($pozadi1);
    ?>

    Diskuze k článku:

    Diskusní příspěvky vyjadřují názory diskutujících, nikoli autora článku.
    Příspěvky nemající souvislost s článkem a příspěvky jejichž jediným účelem je urážet a nadávat budou po zralé úvaze smazány - uvědomte si, že jste na mém písečku.

    #1: Peťulka, přidáno: 27. 3. 2007, 11:07

    Avatar uživatele PeťulkaNo ne.. že bych tomu rozumněla. ale mooc krásný písmenka.. :-D


    #2: Peťulka, přidáno: 27. 3. 2007, 11:08

    Avatar uživatele Peťulkau mě na IE je to pořád maxi.. :-(


    #3: Yo'Sarin, přidáno: 28. 3. 2007, 18:03, web: http://www.yosarin.net

    Avatar uživatele Yo'SarinUž snad nebude. :-)
    Ale vy máte ten prohlížeč nějaký podivný. :-)


    #4: Peťulka, přidáno: 28. 3. 2007, 22:44

    Avatar uživatele PeťulkaTak ty ikonky už vidím normálně.. :-)


    #5: josef, přidáno: 28. 4. 2008, 17:46

    Avatar uživatele josefzajímavé - ale nefunguje v těch nápisech čeština


    #6: Yo'Sarin, přidáno: 29. 4. 2008, 09:35, web: http://www.yosarin.net

    Avatar uživatele Yo'SarinTo je asi pravda - ty defaultní fonty IMO neobsahují diakritiku - to by se dalo vyřešit použitím ttf fontu, který by diakritiku obsahoval - viz funkce imagettftext (je na ní v článku odkaz)


    Přidat nový příspěvek




    Yo'Sarinkovy stránky Blog o všem, co jste už četli jinde Jediný blog se zápornou návštěvností No-more-Didinka I admini mají své dny
    Yo'Sarinkův blok I RSS tu mám Pagerank? Co s ním.
    http://blok.yosarin.net/sekce-6~PC/clanek-37~Ikonky-v-PHP