Autor Zpráva
smiesek
Profil
Ráda bych se zeptala, vypisuju text do obrázku s použitím vlastního fontu, reps. imagettftext
Vše je OK, ale co mě trápí je vzhled písma, kdy ať zkouším třeba použít arial a nebo verdanu, ve výsledku je písmo hrozně zhuštěné a tučné. Existuje ještě nějaký způsob formátování písma a nebo je to třeba ještě někde jinde problém?
Využívám velikost 10 - tušíš čím menší velikost, tím je to neúhledné, ale není možné v připraveném obrázku použít větší písmo.

Pro ukázku přikládám níže obrázek s textem "Písmo arial v velikosti 10."


Děkuju za pomoc.
Chro
Profil
Zkus si vybrat písmo třeba na
http://xphp.sweb.cz/fonts/
a ozvi se, zda problém přetrvává.
smiesek
Profil
Chro:
bohužel pořád stejné, jako by ani se nerozlišoval styl fontu
Chro
Profil
Ukaž prosím skript, kterým vkládáš text do obrázku. Vypadá to, jako by funkce imagettftext vkládala text do obrázku několikrát, podruhé třeba o pixel vedle atp.
smiesek
Profil
Chro:
tady prosím, děkuju

Header ('Content-type: image/png');

$obrazek = imagecreatefrompng("pozadi.png");

$font = "verdana.ttf";

$cerna = imagecolorallocate($obrazek, 0,0,0);

imagettftext($obrazek, 10,0,10,55, $cerna, $font, "Velikost písma.");

imagepng($obrazek);
imagedestroy($obrazek);
Chro
Profil
Nazdrojovaný obrázek s pozadím pozadi.png určitě obsahuje (polo)průhlednost, v tom případě je nutné ještě před funkci imagettftext použít funkci imagealphablending s druhým parametrem TRUE. Řešilo se to třeba zde
http://stackoverflow.com/questions/13312372/imagecreatefrompng-imagettftext-low-quality-text-how-to-anti-alias
a řešení je i v komentářích v manuálu k funkci imagettftext (tam si na stránce vyhledej good text).
smiesek
Profil
Chro:
ano máte pravdu, již funguje, nějak jsem to přehlédla s ohledem na použití png.

Ještě bych se ráda jen zeptala k parametru sklonu písma, měla jsem na to, že to umožní vytvořit text kurzívou, ale jde o sklon celého řádku.

Existují nějaké doplňující znaky, pro stylování písma a nebo se to provádí pomocí tagů (b resp. i)?

Edit: i když ono bude jednodušší vyhledat přímo font bold, reps. italic.

Ještě tedy jednou děkuju za čas a pomoc.
Chro
Profil
Sklon nebo tučnost se řeší přímo v konstrukci TTF fontu. GD knihovna něco jako interpretaci HTML tagů v obrázcích neumí.
Bubák
Profil
Chro:
Sklon nebo tučnost se řeší přímo v konstrukci TTF fontu.
Téhle větě nerozumím, ale naštěstí vím, jak to je. Písmo s jiným řezem je uloženo v jiném souboru, takže ve složce s písmy jsou třebas soubory verdana.ttf, verdanab.ttf, verdanai.ttf, verdanaz.ttf.
smiesek
Profil
ještě bych se ráda dodatečně zeptala kluci, ať nezakládám zbytečně nové téma.

Nyní vykreslení zobrazuju pomocí URL do řádku prohlížeče, např. test.cz/sign.php

Pokud bych jej chtěla zobrazit pomocí tagů img, postačí již pouze vložit danou URL do nich a nebo je nutné ještě něco přes soubor .htaccess nastavit, aby se vědělo, že sing.php má mít právě vlastnosti jako obrázek, resp. png?

A co se týká stylu písma, pokud bych na jednom řádku měla ráda rozlišený text následovně:

Černé písmo - modré - černé písmo.

S tím, že v modrém písmu bude proměnná, která může být libovolně dlouhá.

Tedy pokud bych nyní vypisovala na 3 řádky jednotlivé texty, tak ten třetí řádek nastavím v závilosti na tom druhém, ale co potom, když modrý řetězec bude delší a tím pádem bude překrývat část černého textu v poslední třetí části?

je nějaký způsob, jak spojit konstrukci imagettftext pro více stylů písma, snad z ukázky bude pochopitelné, co mám na mysli



Děkuju
Chro
Profil
Pokud má PHP skript nastavený header s content type obrázku, lze ho použít do atributu src elementu img i s příponou php.
Pozice textů rozličných barev a fontů v rámci 1 obrázku tak, aby navazovaly na sebe, se musí spočítat. První část textu má nějaké počáteční souřadnice imagettftext(X1, Y1). Kolik text zabere pixelů vypočítá funkce imagettfbbox. Druhá část textu bude mít počáteční pozici imagettftext(X2 = X1 + hodnota z funkce imagettfbbox, Y2 = Y1) (například), atd.
smiesek
Profil
Chro:
uf, trošku složité pro mě na pochopení, ale zkusím se chytnout toho výrazu imagettfbbox a pohledat řešení a použití.

Děkuju
Chro
Profil
Kdybys si opravdu, ale opravdu nevěděla rady ani po dlouhém bádání, ozvi se. Napsal bych případně příklad.
smiesek
Profil
Chro:
asi raději poprosím o komentář ke svému postupu, zdali chápu správně a lze to tak korektně použít

budu se zabývat pouze samotným stylováním textu, aby byl do řádku při jakkoliv dlouhé proměnné a nepřekrýval se.

pozadi obrázku mám tedy jako
$obrazek = imagecreatefrompng("pozadi.png");

následně zjistím jeho rozměry
$rozmer_img = GetImageSize($obrazek);

Nyní bych do něj ráda vypisovala větu "Nejnovější je host, přivítejte jej", kdy host bude proměnná a místo něj může být třeba moderátor. Při současném nepoužití imagettfbox by se mi v tomto případě překrýval text moderátor a přivítejte jej.

Začala jsem tedy s úpravou pro definování textových řetězců, budou 3:
$veta_z = "Nejnovější je ";
$nick = "$promenna";
$veta_k = ", přivítejte jej.";

následně jsem u každé zjistila jejich rozměr (pixely)
$rozmer_text1 = ImageTTFBBox($velikost_font, 0, $font, $veta_z);
$rozmer_text2 = ImageTTFBBox($velikost_font, 0, $font, $nick);
$rozmer_text3 = ImageTTFBBox($velikost_font, 0, $font, $veta_k);

ted je nutné k nim dopočítat polohu x a y
$x1 = $rozmer_text1[0] + (imagesx($obrazek) / 2) - ($rozmer_text1[4] / 2) - 94;
$y1 = $rozmer_text1[1] + (imagesy($obrazek) / 2) - ($rozmer_text1[5] / 2) - 32;

výše uvedené je pro mě asi ztěžejní, našla jsem a vyhledala nějaké předávání v tomto tvaru, v mém případě si myslím, že by ani nebylo nutné polohy "zmenšovat" o polovinu (/2)?
Výpočet je pro první řetězec, ale jak navázat nyní na zbývající dva?

Postup
$x2 = $rozmer_text2[0] + (imagesx($obrazek) / 2) - ($rozmer_text2[4] / 2) - 60;
$y2 = $rozmer_text2[1] + (imagesy($obrazek) / 2) - ($rozmer_text2[5] / 2) - 32;
$x3 = $rozmer_text3[0] + (imagesx($obrazek) / 2) - ($rozmer_text3[4] / 2) - 20;
$y3 = $rozmer_text3[1] + (imagesy($obrazek) / 2) - ($rozmer_text3[5] / 2) - 32;

je určitě špatně, protože souřadnici $x zadávám v závislosti na současné délce textu, že?

textový výpis bude již jen
ImageTtfText($obrazek, $velikost_font, 0, $x, $y1, $cerna_font, $font, $veta_z);
ImageTtfText($obrazek, $velikost_font, 0, $x, $y1, $modra_font, $fontb, $nick);
ImageTtfText($obrazek, $velikost_font, 0, $x, $y1, $cerna_font, $font, $veta_k);

nebo jako druhá možnost, co jste naznačil mě napadlo jako
ImageTtfText($obrazek, $velikost_font, 0, $x1, $y1, $cerna_font, $font, $veta_z);
ImageTtfText($obrazek, $velikost_font, 0, $x2=$x1+$x2, $y2=$y1, $modra_font, $fontb, $nick);
ImageTtfText($obrazek, $velikost_font, 0, $x3=$x2+$x3, $y3=$y1, $cerna_font, $font, $veta_k);

Je mi zřejmé, že v tomto případě poloha $y bude stejná, jako jste mi uváděl výše y2=y1, ale trošku se ztrácím nad předáním proměnných $x, reps. pro $nick a $veta_k

Budu ráda za komentář k mému postupu a popř. kde brát důraz na to, proč to nebude fungovat, protože mi příjde, že hodnoty $x zase jen dopočítám v závislosti na řetězci host, nikoliv pro jeho libovolnou délku.

Děkuju
Chro
Profil
<?php
$obr = imagecreate(500, 50);
//zmen na imagecreatefrompng s pouzitim imagealphablending
$font = 'arial.ttf';
$velikost = 10;
$x = 0;
$y = 20;
$text1 = 'Nejnovější je ';
$text2 = 'host';
$text3 = ', přivítejme jej.';
$mezerka = 2;
$bg = imagecolorallocate($obr, 255, 255, 255);
//prvnim pouzitim imagecolorallocate se nastavuje barva pozadi
//u nove vytvoreneho obrazku, u imagecreatefrompng nema smysl (smazat)
$barva1a3 = imagecolorallocate($obr, 0, 0, 0);
$barva2 = imagecolorallocate($obr, 0, 0, 128);
list(, , $sirka1) = imagettfbbox($velikost, 0, $font, $text1);
list(, , $sirka2) = imagettfbbox($velikost, 0, $font, $text2);
imagettftext($obr, $velikost, 0, $x, $y, $barva1a3, $font, $text1);
$x+= $sirka1 + $mezerka;
//pro pozici X textu2 pricteme k $x sirku1 textu1 a malou mezeru
imagettftext($obr, $velikost, 0, $x, $y, $barva2, $font, $text2);
$x+= $sirka2 + $mezerka;
//pro pozici X textu3 pricteme k $x sirku2 textu2 a malou mezeru
imagettftext($obr, $velikost, 0, $x, $y, $barva1a3, $font, $text3);
header('Content-type: image/png');
imagepng($obr);
imagedestroy($obr);
?>
smiesek
Profil
Chro:
Tak již tedy pochopeno dle toho vzoru, který jste zaslal, myslím, že nyní by to vše již mělo být OK.
Já jsem na to šla úplně špatně.

Jen bych se ráda zeptala na chování zápisu, pokud bych vypisovala něco jako:

Současný stav: 12/36

text_modrý: současný stav
text_černý: :
text_zelený: 12
text_černý: /36

kdy hodnota "12" bude proměnná, a může být libovolně místná

Logicky vzato, aby to vypadalo úhledně musím taky pro zbytek řetězce "/36" nastavit mezeru, ale jakmile třeba dosadím nějaké jiné číslo "1234" tak se mezera mezi "1234" a "/36" změní.
Vlastně i při použití samotné dvojtečky se mezera projeví jinak ":"

Mám to brát tak, že se to ještě celkově vypočítává k rozměru pozadí obrázku?

Děkuju
Chro
Profil
Čistě typograficky, v řetězci "[číslo]/[číslo]" by žádná mezera být neměla. Jak to vykreslí PHP+GD záleží na TTF fontu. Za 8 ta mezera může být menší, za 1 větší. Ošéfovat to ve skriptu třeba různýma podmínkama by bylo složitější, prostě od toho nelze čekat zázraky, ty umí HTML+CSS. :) Tam, kde nechceš mezeru mezi částmi skládaného textu, tam nepřičítej před voláním funkce imagettftext k $x proměnnou $mezera. Dotaz na konci jsem asi nepochopil. Rozměr pozadí v obrázku pozadi.png je pevně daný a dostatečně široký na všechny možné kombinace vkládaných řetězců (?).
smiesek
Profil
Chro:
no jde o to, že se to chová různě při různé délce modrého textu, viz:


tak jestli je to OK a nebo někde ještě se chybně počítá

měním pouze délku řetezce toho modrého textu, ale to samé se stane pokud budu měnit zelené číslo.

Pracuju s řádky jako jsem uvedla výše - 4 řádky řetezců.

Děkuju
smiesek
Profil
Chro:
ještě jste mě navedl na myšlenku a asi to vyřeším podmínkami, které nastavím s ohledem na počet znaků řetězce.
Chro
Profil
smiesek [#18]:
Uvedl jsem příklad pro složení tří částí, nyní skládáš ze čtyř. Tzn. že skript byl nějak upraven/doplněn a bez nahlédnutí do kódu a přístupu k použitému obrázku jako pozadí nemám jak poradit.
smiesek
Profil
Chro:
myslela jsem, že to půjde stejným postupem, ať se jedná o jakýkoliv částí, tedy jestli mohu přiložit k nahlédnutí, kdy pracuju s velikostí pozadí tedy 370x130
$obrazek = imagecreatefrompng("sign.png");
$x = 10;
$y = 40;

$veta_z = "Celkový počet";
$predmet = "mincí";
$dvojtecka = ":";
$pocet = "21";
$veta_k = "/43 (48,84%)";

list(, , $sirka1) = ImageTTFBBox($velikost_font, 0, $font, $veta_z);
list(, , $sirka2) = ImageTTFBBox($velikost_font, 0, $font, $predmet);
list(, , $sirka3) = ImageTTFBBox($velikost_font, 0, $font, $dvojtecka);
list(, , $sirka4) = ImageTTFBBox($velikost_font, 0, $font, $pocet);
list(, , $sirka5) = ImageTTFBBox($velikost_font, 0, $font, $veta_k);


ImageTtfText($obrazek, $velikost_font, 0, $x, $y, $cerna_font, $font, $veta_z);
$x+= $sirka1 + $mezera;
ImageTtfText($obrazek, $velikost_font, 0, $x, $y, $modra_font, $fontb, $predmet);
$x+= $sirka2 + $mezera;
ImageTtfText($obrazek, $velikost_font, 0, $x, $y, $cerna_font, $font, $dvojtecka);
$x+= $sirka3 + $mezera;
ImageTtfText($obrazek, $velikost_font, 0, $x, $y, $zelena_font, $fontb, $pocet);
$x+= $sirka4 + $mezera;
ImageTtfText($obrazek, $velikost_font, 0, $x, $y, $cerna_font, $font, $veta_k);

ImagePng($obrazek);

vytáhla jsem prosím to nejpodstatnější, průhlednost a nebo velikosti textu, barvu a pod, tak mám ošetřeno.

Děkuju za pomoc a upozornění, a vysvětlení, proč tedy nelze takhle pouze skládat jednotlivé části řetězce.
Chro
Profil
Zjišťuješ šířky textů v pouze jediném fontu ($font), ale texty vypisuješ střídavě v normálním ($font) a tučném ($fontb) fontu. Je jasné, že tučnější písmo bude zabírat větší šiřku.
smiesek
Profil
Chro:
tak to mě nenapadlo, nevěnovala jsem tomu pozornost, moje blbost a děkuju za upozornění, nyní tedy již vše jak má.
Ještě jednou děkuju, pomohlo, půjdu alespoň dále zase směle studovat tvorbu a výpis do grafů :)
Chro
Profil
Máš zač. Cenu za trpělivost s dotazujícím si udělím sám. :)
smiesek
Profil
Chro:
dobrá, děkuju

ještě prosím, to jsem se zaměřila na stylování vykreslení textu, můžeš se mi ještě podívat, zdali správně a korektně zjišťuju velikost?

Header ('Content-type: image/png');

$obrazek = imagecreatefrompng("sing.png");

imagealphablending($obrazek, true);
imagesavealpha($obrazek, true);

$size_img = GetImageSize($obrazek);

... doplnění stylu dat textu ...

ImagePng($obrazek);

ImageDestroy($obrazek);

Popř. je nějaké řešení do prohlížeče přímo vepsat i ty rozměry jako součástí URL a aby se to zobrazilo jako obrázek i nadále? Protože takhle mi to při vložení do tagů IMG píše, že nelze zjistit rozměry - resp. hlavně pokud je někde uvedeno max. rozměry, např. max. rozměry 800x200 a mě to nezobrazí i když jsou moje rozměry 400X150
Chro
Profil
Na phpbb.cz jsi se o svém problému rozepsala konkrétněji...

Informace o rozměrech obrázku je zasílána v proudu dat - výstupu z funkce imagepng - a každý běžně používaný prohlížeč tuto informaci dostane a podle ní v daných rozměrech obrázek zobrazí.

Že ti jde obrázek vygenerovaný skriptem na phpbb fóru zobrazit v příspěvku, avšak nejde zobrazit v podpisu, tedy není chybou v obrázku.

Chyba je v nastavení serveru, na kterém phpbb fórum běží. Pokud jsou v nastavení fóra nastaveny max. rozměry obrázku v podpisu, dotazuje se aplikace vzdáleného serveru, na kterém je obrázek uložen, funkcí getimagesize protokolem HTTP na rozměry obrázku. Pokud je na serveru provozující fórum zakázáno allow_url_fopen, funkce nezjistí nic a aplikace logicky vypíše "nelze zjistit rozměry obrázku" a obrázek se nezobrazí protože se neví, zda rozměry nepřekročil nastavení max. povolených rozměrů.
smiesek
Profil
Chro:
co jsem se dívala na nastavení toho serveru, jak jsi se zmiňoval o allow_url_fopen, tak je povoleno, jde o to, že pokud je to nastaveno na neomezeně, tak se to zobrazí, vše OK, ale neumí to prostě tu velikost přečíst, nebude tedy nějaká možnost jak tu velikost dávat přímo?

Zkoušela jsem i přenastavení pomocí .htaccess, aby místo koncovky php se dávalo png, ale výsledek stejný.
Chro
Profil
Hm, tak to nevím. Taky nevím vše a některé info si googluju. Asi špatný překlad z AJ. Nevím, zkus do podpisu vložit třeba
 
a/nebo nepoužívej v PHP skriptu header s content type image/png ale obrázek si ulož fo filesystému a přesmeruj na něho (možná se potřebuje odesílat více kompletních hlaviček).
imagepng($obr, 'sign.png');
header('Location: sign.png');
exit;



TAK ZNOVA:
Hm, tak to nevím. Taky nevím vše a některé info si googluju. Asi špatný překlad z AJ. Nevím, zkus do podpisu vložit třeba
[ I M G ]http://www.test.cz/sign.php?extension=.png[ / I M G ]
a/nebo nepoužívej v PHP skriptu header s content type image/png ale obrázek si ulož fo filesystému a přesmeruj na něho (možná se potřebuje odesílat více kompletních hlaviček).
imagepng($obr, 'sign.png');
header('Location: sign.png');
exit;
smiesek
Profil
Chro:
no to bude asi celé zapeklité, což nevyřeším.
I tak děkuju.
smiesek
Profil
kdysi jsem se zabývala výše uvedeným dynamickým podpisem a nyní bych se ráda pokusila vykreslit graf, ale prosím nemohu nikde najít odůvodnění a princip načtení do pole následující řádek:
list(, , $sirka2) = imagettfbbox($velikost, 0, $font, $text2);

našla jsem pouze to, že to vrací hodnoty x a y, ale tím pádem by se to mělo posunovat směrem dolů po y ose, nikoliv x ne?

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: