Obrázky a PHP – práce s textem a rozměry

14. srpna 2003

Tentokrát se nejprve podíváme na nějaké funkce pro práci s textem v obrázcích a následně i na funkce zjišťující a pracující s rozměry obrázku. Nakonec je připraven ukázkový kód, v němž si získané znalosti vyzkoušíme na praktickém příkladě.

Funkce pro práci s textem

ImageChar (int obr, int rozmer_pismo, int x, int y, string znak, int barva);
Funkce vykresluje jeden znak znak barvy barva, umístěný v obrázku obr na souřadnicích x, y. Parametr rozmer_pismo akceptuje číslice 1 až 5, kde 1 je nejmenší možná a 5 největší možná velikost znaku, přičemž větší parametr písmo automaticky formátuje na největší možnou výšku.

ImageCharUp (int obr, int rozmer_pismo, int x, int y, string znak, int barva);
Funkce s parametry stejnými jako předchozí ImageChar, rozdíl tkví v zobrazení znaku. Zatímco ImageChar zobrazí znak horizontálně, ImageCharUp tak učiní ve směru vertikálním.

ImageString (int obr, int rozmer_pismo, int x, int y, string retez, int barva);
Funkce vykresluje řetězec znaků retez barvy barva, umístěný v obrázku obr na souřadnicích x, y. Parametr rozmer_pismo je stejný jako u funkce ImageChar a akceptuje číslice 1 až 5, udávající velikost písma.

ImageStringUp (int obr, int rozmer_pismo, int x, int y, string znak, int barva);
Funkce s parametry stejnými jako u předchozí ImageString, rozdíl tkví v zobrazení řetězce. Zatímco ImageString zobrazí řetězec horizontálně, ImageStringUp tak učiní ve směru vertikálním.

ImageFontWidth (int rozmer_pismo);
Funkce vrací šířku písma rozmer_pismo v pixelech. Protože jde o neproporciální písmo se stejnou šířkou všech znaků, lze díky tomuto údaji vypočítat souřadnice pro umístění řetězce například do středu obrázku.

ImageFontHeight (int rozmer_pismo);
Funkce vrací výšku písma rozmer_pisma v pixelech, čehož lze v kombinaci s ImageFontWidth využít k různému vypočítávání umístění textu do obrázku

ImageTTFText (int obr, int vyska_pisma, int uhel, int x, int y, int barva, string soubor_pismo, string retez);
Pokud vám nevyhovuje standardní písmo, snad vám přijde vhod některé truetypové, k jehož načtení slouží právě tato funkce. Ta vykresluje řetězec znaků retez na obrázek obr barvou barva na souřadnice x,y pod úhlem uhel, výškou písma vyska_pisma a s využitím TrueType písma nacházejícím se na soubor_pisma. Pokud jste si jisti, že uživatel používá operační systém Windows, je zde možnost nastavit cestu k danému písmu tak, aby se načetl z uživatelova disku (například C:\Windows\Fonts\pismo.ttf), v opačném případě umístěte soubor na vámi používaný server a uživatel písmo načte z něj.

ImageTTFBBox (int velikost_pisma, int uhel_pisma,string cesta_soubor, string text);
Pokud chcete vykreslit nějaký text pomocí truetype písem a ještě k tomu pod určitým úhlem, pak vás třeba bude zajímat, jakou oblast text zabere. Právě k tomu složí funkce ImageTTFBBox. Zpravidla je tato funkce volána do nějaké proměnné a vrací pole s osmi prvky – body, které vymezují zabranou oblast:

  • Index 0 – Levý dolní bod na X
  • Index 1 – Levý dolní bod na Y
  • Index 2 – Pravý dolní bod na X
  • Index 3 – Pravý dolní bod na Y
  • Index 4 – Pravý horní bod na X
  • Index 5 – Pravý horní bod na Y
  • Index 6 – Levý horní bod na X
  • Index 7 – Levý horní bod na Y

Díky těmto údajům lze vypočítat souřadnice umístění tak, aby daný text po zavolání kreslící funkce ImageTTFText byl umístěn například přesně do středu obrázku.

Funkce pracující s rozměry obrázku

ImageSX (int obr);
Funkce vrací šířku obrázku obr v pixelech.

ImageSY (int obr);
Funkce vrací výšku obrázku obr v pixelech.

GetImageSize (int umisteni);
Funkce GetImageSize je nejkomplexnější funkcí, zjišťující informace o obrázku. Zpravidla bývá volána do nějaké proměnné a vrací pole se čtyřmi prvky:

  • Index 0 – vrací šířku obrázku
  • Index 1 – vrací výška obrázku
  • Index 2 – vrací typ obrázku (vrací číslice: 1 – GIF, 2 – JPG, 3 – PNG)
  • Index 3 – vrací řetězec pro HTML element <IMG> s rozměry obrázku (HEIGHT=HODNOTA WIDTH=HODNOTA)

ImageCopy (int cil_obr, int zdroj_obr, int cil_x, int cil_y, int zdroj_x, int zdroj_y, int zdroj_sirka, int zdroj_vyska);
Funkce kopíruje vybranou část obrázku obdélníkového tvaru zdroj_obr šířky zdroj_sirka a výšky zdroj_vyska, začínající na souřadnicích zdroj_x a zdroj_y, na souřadnice cílového obrázku cil_x a cil_y.

ImageCopyMerge (int cil_obr, int zdroj_obr, int cil_x, int cil_y, int zdroj_x, int zdroj_y, int zdroj_sirka, int zdroj_vyska, int rozsah);
Funkce ImageCopyMerge je takřka totožná s předchozí ImageCopy, avšak s jedním rozdílem – poslední parametr rozsah je zde navíc. Ten určuje, jakým způsobem bude daná část zdrojového obrázku do cílového vložena, neboť tato funkce se snaží vkládanou část sloučit barevně s okolím a platí, že čím nižší číslo, tím více se odstín vkládané části přibližuje pozadí a při zadání nuly se dokonce neprovede žádná akce. Naopak při zadání nejvyššího platného čísla z povoleného rozsahu, stovky, je akce totožná s akcí u funkce ImageCopy.

ImageCopyResized (int cil_obr, int zdroj_obr, int cil_x, int cil_y, int zdroj_x, int zdroj_y, int zdroj_sirka, int zdroj_vyska, cil_sirka, cil_vyska);
Funkce kopíruje vybranou obdélníkovou část ze zdrojového obrázku zdroj_obr do cílového obrázku cil_obr podobně jako funkce ImageCopy, avšak s tím rozdílem, že vkládaný obrázek nemusí být stejných rozměrů, ty můžeme pomocí parametrů cil_sirka a cil_vyska určit sami, přičemž PHP se postará o potřebné zúžení či roztažení.

Ukázková aplikace

Nyní můžeme získané znalosti vyzkoušet na ukázkovém příkladu, v němž si vytvoříme aplikaci, kterou je možno využít například v redakčním systému, kdy chceme podepisovat redaktorem vkládané obrázky logem našeho serveru a ještě do jeho záhlaví vložit komentář.

Nejprve redaktor musí obrázek vložit, což mu umožníme pomocí elementu <input> s nastaveným typovým atributem file. Dále je potřeba nastavit atribut enctype v elementu form na multipart/form-data. Aby byla ukázka názornější, přidáme ještě pole pro vložení komentáře, který se vykreslí přímo do obrázku.

<!– vlozeni.htm –>
<form action=’obsluha.php‘ method=’post‘ enctype=’multipart/form-data‘>
Soubor (pouze .PNG): <input type=’file‘ name=’obrazek‘> <br />
Komentář: <input type=’text‘ name=’komentar‘> <br />
<input type=’submit‘ value=’Posli‘>
</form>

Po odeslání formuláře se přesuneme na stránku obsluha.php. Zde je potřeba odeslaný soubor pomocí funkce move_uploaded_file zkopírovat do námi vybraného adresáře a pokud máte zájem, ještě předtím soubor zkontrolovat, zda vyhovuje vašim požadavkům. Kromě $obrazek máme totiž k dispozici i tuto sadu proměnných s příponami:

  • $obrazek_name – jméno a cesta k souboru u klienta, který soubor odeslal
  • $obrazek_type – typ souboru
  • $obrazek_size – velikost souboru v bytech

Po zkopírování a uložení obrázku ho znovu načteme a nyní provedeme požadované úpravy. Pomocí funkce ImageTTFBBox zjistíme délku odeslaného komentáře v pixelech a podle toho vyplníme levý horní roh obrázku černým obdelníkem, do kterého následně pomocí funkce ImageTTFText zapíšeme bílou barvou odeslaný komentář. Ještě obrázek obohatíme o logo serveru, které umístíme do pravého dolního rohu tak, aby na šířku zabíralo třetinu obrázku a upravena bude také výška loga tak, aby se poměry stran nezměnily. Následně vše uložíme a dílo je hotovo.

<!– obsluha.pho –>
$font=“C:\Windows\Fonts\Tahoma.ttf“; // cesta k souboru s fonty
$metriky_obr=GetImageSize($obrazek); // zjištění rozměrů obrázku
if ($obrazek_size>200000) { // kontrola velikosti obrázku
   echo(„Obrázek je příliš velký. Proveďte prosím větší kompresi.“);
   exit;
}
if ($metriky_obr[2]!=3) { // Kontrola typu
   echo(„Odeslali jste špatný typ obrázku.“);
   exit;
}
if(($metriky_obr[0] or $metriky_obr[1])<200) { // Kontrola rozměrů
   echo(„Odeslali jste obrázek příliš malých rozměrů“);
   exit;
}
$cesta=“obrazky/img“ . date(„ymdhis“) . „.png“;
$kopirovani=move_uploaded_file($obrazek, $cesta); // Zkopírování odeslaného souboru
if(!$kopirovani) {
   echo(„Kopírování souboru se nepovedlo. Opakujte prosím požadavek.“);
   exit;
}
$picture=ImageCreateFromPNG($cesta); // Načtení uloženého obrázku
$logo=ImageCreateFromPNG(„logo.png“); // Načtení loga serveru
$bila=ImageColorAllocate($picture, 255, 255, 255); // Alokace barev
$cerna=ImageColorAllocate($picture, 0, 0, 0);
$metriky_koment=ImageTTFBBox(10, 0, $font, $komentar); // Zjištění textem zabírané oblasti
$metriky_pic=GetImageSize($cesta);
/* Vložení černého podkladu do levého horního rohu a následné vypsání komentáře */
ImageFilledRectangle($picture, 0, 0, ($metriky_koment[2]+5), ($metriky_koment[3]+20), $cerna);
ImageTTFText($picture, 10, 0, 2, 15, $bila, $font, $komentar);
$logo_x=$metriky_pic[0]/3*2;
$logo_y=$metriky_pic[1]-($metriky_pic[0]/3*27/100);
ImageCopyResized($picture, $logo, $logo_x, $logo_y, 0, 0, ($metriky_pic[0]/3), ($metriky_pic[0]/3*27/100), 180, 50); // Úprava rozměrů loga a jeho umístění do obrázku
ImagePNG($picture, $cesta); // Přepsání obrázku

Výsledný obrázek může vypadat například takto:

vygenerovaný obrázek

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Další článek ceses
Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *