Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Generowanie grafiki GD, TEKST
Gray
post
Post #1





Grupa: Zarejestrowani
Postów: 127
Pomógł: 0
Dołączył: 5.04.2010

Ostrzeżenie: (10%)
X----


Witam, znalazłem pewien tutorial odnośnie tworzenia grafiki za pomocą GD. Zmodyfikowałem delikatnie kod który tam był opisany i w efekcie posiadam taki kod:

  1. <?php
  2. $tekst=$_POST['tekst'];
  3.  
  4. $data_img=date('dmYHis');
  5. $uploaddir = 'img/upload/'.$data_img.'-slowo.png';
  6.  
  7. $im = @imagecreate(200, 100)
  8. or die("Cannot Initialize new GD image stream");
  9. $background_color = imagecolorallocate($im, 0, 0, 0);
  10. $text_color = imagecolorallocate($im, 255, 255, 255);
  11. imagestring($im, 1, 5, 5, $tekst, $text_color);
  12. imagepng($im, $uploaddir);
  13. ImageDestroy($im);
  14. ?>


Oczywiście do jego obsługi wystarczy prosty formularz z oknem textowym "tekst". Ale do rzeczy, kod ten tworzy czarny prostokąt i na nim biały napis. Chciał bym móc manipulować tym tekstem i wielkością prostokąta. Dokładniej mówiąc chciał bym móc ustawić marginesy dla tekstu i jego wyśrodkowanie lub wyjustowanie, odpowiednie zawijanie wierszy w przypadku dłuższego tekstu, skalowanie wielkości prostokąta względem ilości tekstu i wielkości czcionki lub na odwrót, wielkości czcionki względem wielkości prostokąta. I czy jest możliwość stosowania zaawansowanych opcji do samej czcionki, takich jak używa się w css.

Pozdrawiam,
Gray

Ten post edytował Gray 23.10.2011, 20:49:29
Go to the top of the page
+Quote Post
2 Stron V   1 2 >  
Start new topic
Odpowiedzi (1 - 19)
croc
post
Post #2





Grupa: Zarejestrowani
Postów: 706
Pomógł: 108
Dołączył: 12.03.2010

Ostrzeżenie: (0%)
-----


PHP GD nie posiada takich opcji. Jedyne co możesz zrobić to poszukać gotowych rozwiązań lub samemu się pobawić matematycznie, ale to będzie dużo pracy.
Go to the top of the page
+Quote Post
Pawel_W
post
Post #3





Grupa: Zarejestrowani
Postów: 1 675
Pomógł: 286
Dołączył: 15.06.2009
Skąd: Wieliczka

Ostrzeżenie: (0%)
-----


imagettfbbox
to Ci pomoże do zabawy z wielkością prostokąta (marginesy itp.)

w przykładzie masz pokazane jak wyśrodkować tekst, na siłę mógłbyś za pomocą tej funkcji robić zawijanie wierszy
Go to the top of the page
+Quote Post
Gray
post
Post #4





Grupa: Zarejestrowani
Postów: 127
Pomógł: 0
Dołączył: 5.04.2010

Ostrzeżenie: (10%)
X----


Dzięki Paweł_W za podpowiedz, w gruncie rzeczy myslałem o tej funkcji ale łudziłem się, że będzie coś co wymaga mniej kombinowania. Jakoś to ogarnę jednak jak wyśrodkować czcionkę względem siebie, tzn. po podzieleniu tekstu na wiersze funkcją wordwrap() aby układały się one pod sobą wyśrodkowane a nie ustawione do lewej? coś w tym stylu:

aaaaaaaaaaaaa
aaaaa
aaaaaaaaa


Czyli <center> lub jakiś sposób na wyjustowanie?

Ten post edytował Gray 24.10.2011, 00:15:21
Go to the top of the page
+Quote Post
croc
post
Post #5





Grupa: Zarejestrowani
Postów: 706
Pomógł: 108
Dołączył: 12.03.2010

Ostrzeżenie: (0%)
-----


W odpowiedzi na to pytanie nie ma nic o czym nie wiesz. Tak jak napisałem powyżej, to zabawa matematyczna - musisz podzielić tekst na słowa i sprawdzać czy kolejne mieszczą się w wierszu. Jeśli nie, to schodzisz niżej. Możesz też w ten sposób próbować wyjustować, tzn. jak już masz gotowy wiersz, to obliczyć odstępy między słowami/literami takie, by zapełnić wiersz.
Go to the top of the page
+Quote Post
Gray
post
Post #6





Grupa: Zarejestrowani
Postów: 127
Pomógł: 0
Dołączył: 5.04.2010

Ostrzeżenie: (10%)
X----


Hmm, z tym dzieleniem na słowa i sprawdzaniem czy się mieszczą jest problem. Sprawdzić to potrafię tylko pod względem ilości znaków, w sumie nawet nie tyle potrzeba sprawdzać wyrazy co wiersze. Jednak jak sprawdzić czy ciąg znaków mieści się w danym polu pod względem szerokości w pikselach a nie ilości znaków?
Jak wiadomo każda literka jest innej szerokości, i tak o ile wpasuję sobie idealnie ciąg znaków iiiiiiiiii to inny ciąg np. WWWWWWWWWW kompletnie nie będzie pasował mimo takiej samej ilości znaków.

Istnieje jakaś funkcja lub sposób podobny do wordwrap(); która jako wyznacznik miejsca dzielenia ciągu przyjmuje szerokość w pikselach a nie ilość znaków?

Jestem początkujący w PHP dlatego proszę o pomoc i ewentualne dokładne wytłumaczenie.

Pozdrawiam,
Gray.
Go to the top of the page
+Quote Post
dwwa
post
Post #7





Grupa: Zarejestrowani
Postów: 47
Pomógł: 1
Dołączył: 14.09.2011

Ostrzeżenie: (0%)
-----


jak dobrze pamiętam to funkcja imageftbbox() ci pomoże

tu zobacz
http://www.viawww.wortale.net/135-Centerow...u-w-PHP-GD.html
Go to the top of the page
+Quote Post
Gray
post
Post #8





Grupa: Zarejestrowani
Postów: 127
Pomógł: 0
Dołączył: 5.04.2010

Ostrzeżenie: (10%)
X----


Ta właśnie jestem w trakcie maglowania tej funkcji, zrobiłem takie coś i wydaje się w miarę działać:

  1. <?php
  2. // Create a 300x150 image
  3. $im = imagecreatetruecolor(550, 400);
  4. $black = imagecolorallocate($im, 0, 0, 0);
  5. $white = imagecolorallocate($im, 255, 255, 255);
  6.  
  7. // Set the background to be black
  8. $background_color = imagecolorallocate($im, 0, 0, 0);
  9.  
  10. // Path to our font file
  11. $font = './book.ttf';
  12.  
  13. // ustawienie tekstu
  14. $text = "FGHFGH GTH RHGTRGH TRTRIOHR OT GGUGH G GEGU EUI OGHGUIOG UIOG UO GEFUIOGERU IOGERUIOG UIO ERO EEUIOG GEHGERUI GHIOJEOG VO EO QEROGI ER";
  15.  
  16. ////////////////////////////////////////////////////////PĘTLA
  17. $wielkoscczcionki=20;
  18. $enter=40;
  19. $szerokosc=531;
  20. while($szerokosc>490){
  21.  
  22. $newtext = wordwrap($text, $enter, "\n", TRUE);
  23. $bboxx = imagettfbbox($wielkoscczcionki, 0, $font, $newtext);
  24. $szerokosc = $bboxx[4] - $bboxx[6];
  25. $enter--;
  26. }
  27. /////////////
  28.  
  29. // Write it
  30. imagettftext($im, $wielkoscczcionki, 0, 30, 40, $white, $font, $newtext);
  31.  
  32.  
  33. // Output to browser
  34. header('Content-Type: image/png');
  35.  
  36. imagepng($im);
  37. imagedestroy($im);
  38. ?>


Chciał bym prosić kogoś o jakieś wskazówki szczególnie dotyczące pętli while, pisałem ją sam, wydaje się działać ale mogłem coś zawalić.
Go to the top of the page
+Quote Post
croc
post
Post #9





Grupa: Zarejestrowani
Postów: 706
Pomógł: 108
Dołączył: 12.03.2010

Ostrzeżenie: (0%)
-----


Twoja metoda nie ma sensu. Porównaj wyniki z użyciem "słów" złożonych z samych liter "i" z takich z samymi "W". Mój sposób jest chyba jedynym sensownym. Badanie szerokości bloku po każdym dodaniu słowa. Kolega Pawel_W podał Ci nazwę funkcji do badania szerokości bloku.
Go to the top of the page
+Quote Post
dwwa
post
Post #10





Grupa: Zarejestrowani
Postów: 47
Pomógł: 1
Dołączył: 14.09.2011

Ostrzeżenie: (0%)
-----


http://pl.php.net/manual/en/function.imagettftext.php

a dokładniej chodzi mi o funkcje napisaną przez użytkownika w komentarzu do funkcji imagettftext
  1. <?php
  2. function wrap($fontSize, $angle, $fontFace, $string, $width){
  3.  
  4. $ret = "";
  5.  
  6. $arr = explode(' ', $string);
  7.  
  8. foreach ( $arr as $word ){
  9.  
  10. $teststring = $ret.' '.$word;
  11. $testbox = imagettfbbox($fontSize, $angle, $fontFace, $teststring);
  12. if ( $testbox[2] > $width ){
  13. $ret.=($ret==""?"":"\n").$word;
  14. } else {
  15. $ret.=($ret==""?"":' ').$word;
  16. }
  17. }
  18.  
  19. return $ret;
  20. }
  21. ?>

a jak to ci nie pomoże to szukaj w google "php gd pietrzenie tekstu"

Ten post edytował dwwa 25.10.2011, 20:23:25
Go to the top of the page
+Quote Post
croc
post
Post #11





Grupa: Zarejestrowani
Postów: 706
Pomógł: 108
Dołączył: 12.03.2010

Ostrzeżenie: (0%)
-----


No właśnie. Dokładnie o coś takiego chodzi. Problem w tym, że ta funkcja testuje jedynie czy słowo mieści się w wierszu, a to tylko wierzchołek góry lodowej - działaj, kolego.
Go to the top of the page
+Quote Post
Gray
post
Post #12





Grupa: Zarejestrowani
Postów: 127
Pomógł: 0
Dołączył: 5.04.2010

Ostrzeżenie: (10%)
X----


Wiem, że podał, już wcześniej ktoś inny ją podał i ja ją wykorzystuję w pętli którą podałem wyżej:

  1. $wielkoscczcionki=20;
  2. $enter=40;
  3. $szerokosc=531;
  4. while($szerokosc>490){
  5.  
  6. $newtext = wordwrap($text, $enter, "\n", TRUE);
  7. $bboxx = imagettfbbox($wielkoscczcionki, 0, $font, $newtext);
  8. $szerokosc = $bboxx[4] - $bboxx[6];
  9. $enter--;
  10. }


Sprawdza ona szerokość podzielonego na wiersze tekstu przy początkowo przyjętej ilości znaków po której następuje "enter" jako 40. Jeśli wykryje, że ta szerokość jest większa niż pożądana to zmniejsza ilość znaków po których następuje "enter" o 1. Będzie zmniejszało długość pojedynczego wiersza aż całość zmieści się w podanej szerokości czyli 490.

Staram się napisać teraz podobną pętlę do wysokości, jednak nie będzie redukowała ona długości pojedynczego wiersza, zamiast tego będzie zmniejszała wielkość czcionki. Jednak póki co nie bardzo mi to wychodzi.
Go to the top of the page
+Quote Post
croc
post
Post #13





Grupa: Zarejestrowani
Postów: 706
Pomógł: 108
Dołączył: 12.03.2010

Ostrzeżenie: (0%)
-----


wordwrap jest tutaj bezużyteczny.
Go to the top of the page
+Quote Post
Gray
post
Post #14





Grupa: Zarejestrowani
Postów: 127
Pomógł: 0
Dołączył: 5.04.2010

Ostrzeżenie: (10%)
X----


tzn. nie wiem czy jest bezużyteczny w bardzo zoptymalizowanej wersji której ja pewnie nie wymyślę, jednak w mojej pętli wordwrap dzieli ciąg znaków na wiersze jeden pod drugim, w każdym wierszu max 40znaków. I jeśli pętla wykryje ze 40 znaków to za dużo przy ustalonej szerokości to zmniejsza wiersz o 1. Wtedy wordwrap dostaje polecenie podziału ciągu na wiersze jeden pod drugim, 39 znaków na wiersz itd.

Oczywiście można zauważyć, że imageftbbox() sprawdza szerokość już po podziale przez wordwrap.

Ten post edytował Gray 25.10.2011, 20:36:41
Go to the top of the page
+Quote Post
croc
post
Post #15





Grupa: Zarejestrowani
Postów: 706
Pomógł: 108
Dołączył: 12.03.2010

Ostrzeżenie: (0%)
-----


Bezużyteczny, bo - jak napisałem powyżej - jeden ciąg długości X znaków może być 2 razy dłuższy/krótszy niż drugi. Optymalizacją się nie martw, ale co się stanie jak wordwrap wygeneruje Ci tak, że zmieściłoby się jeszcze jedno słowo? Nie martw się optymalizacją zanim nie działa jak powinno (IMG:style_emoticons/default/smile.gif) Zrób explode(' ', $string) i dodawaj klocek po klocku. Wchodzi - dodajemy do wiersza. Nie wchodzi? Schodzimy niżej.
Go to the top of the page
+Quote Post
Pawel_W
post
Post #16





Grupa: Zarejestrowani
Postów: 1 675
Pomógł: 286
Dołączył: 15.06.2009
Skąd: Wieliczka

Ostrzeżenie: (0%)
-----


obiło mi się kiedyś o uszy coś takiego jak phpHyphenator, który dzieli tekst tak, aby ładnie się "justował" - może to Ci pomoże, chociaż nie wiem dokładnie czy cały skrypt jest napisany w php (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
croc
post
Post #17





Grupa: Zarejestrowani
Postów: 706
Pomógł: 108
Dołączył: 12.03.2010

Ostrzeżenie: (0%)
-----


Temat jest bardzo ciekawy. To może przydać: http://www.google.pl/search?gcx=w&sour...stify+algorithm

EDIT
Ja jestem w trakcie pisania nakładki obiektowej dla GD (bardziej dla praktyki niż użyteczności). Zainspirowany tym tematem zacząłem robić metodę wypisywania tekstu jako bloku. Póki co zrobiłem sobie centrowanie tekstu. Efekt jest taki:
(IMG:http://img692.imageshack.us/img692/8459/47941390.png)

Kod metody:
  1. public function text($text, $width, $font, $size, Color $color, $x, $y) {
  2. $fontFileName = './'.$font.'.ttf';
  3. $words = explode(' ', $text);
  4. $rows = array();
  5. $row = '';
  6. $rowWidth = 0;
  7. foreach($words as $word) {
  8. $element = ($row === '' ? null : ' ').$word;
  9. $box = imagettfbbox ($size, 0, $fontFileName, $element);
  10. $elementWidth = $box[2] - $box[0];
  11. if($rowWidth + $elementWidth <= $width) {
  12. $row .= $element;
  13. $rowWidth += $elementWidth;
  14. }
  15. else {
  16. array_push($rows, $row);
  17. $row = $word;
  18. $rowWidth = $elementWidth;
  19. }
  20. }
  21. foreach($rows as $row) {
  22. $box = imagettfbbox ($size, 0, $fontFileName, $row);
  23. imagettftext($this->source, $size, 0, $x + ($width - ($box[2] - $box[0]) >> 1), $y, $color->identifier, $fontFileName, $row);
  24. $y += $size << 1;
  25. }
  26. }

A powyższy obrazek wywołałem tak:
  1. $image = new Image(400, 300, new Color(0, 0, 0));
  2. $image->gradient(new Color(235, 245, 255), new Color(215, 235, 255));
  3. $image->text(file_get_contents('text.txt'), $image->getWidth(), 'arial', 12, new Color(0, 123, 255), 0, 20);
  4. $image->show();


Metoda oczywiście zawiera błędy. Fajnie byłoby, gdyby udało się stworzyć rozwiązanie, które służyłoby do wypisywania tekstu z dowolnym sposobem wyrównania.

Zastanawia mnie jak najlepiej rozwiązać justowanie:
  1. wydłużać tylko spacje
  2. wydłużać spacje i odstępy między literami po równo
  3. wydłużać spacje bardziej niż odstępy między literami

Wydaje mi się, że sposób 3. jest najlepszy, ale jaki współczynnik obrać? (IMG:style_emoticons/default/smile.gif)

Ten post edytował croc 26.10.2011, 00:16:36
Go to the top of the page
+Quote Post
Gray
post
Post #18





Grupa: Zarejestrowani
Postów: 127
Pomógł: 0
Dołączył: 5.04.2010

Ostrzeżenie: (10%)
X----


Heh fajnie, że kogoś to zainspirowało. Ja jestem początkujący w PHP więc raczej w samym pisaniu niewiele pomogę. Jedynie zauważyłem, że w programach tekstowych np. Word justowanie polega na zwiększaniu spacji pomiędzy wyrazami. Najlepiej w całym bloku wszystkie spacje zwiększać o tyle samo i ewentualne nadwyżki/niedobory redukować spacjami na końcu wiersza.
Go to the top of the page
+Quote Post
croc
post
Post #19





Grupa: Zarejestrowani
Postów: 706
Pomógł: 108
Dołączył: 12.03.2010

Ostrzeżenie: (0%)
-----


Cytat(Gray @ 26.10.2011, 01:53:48 ) *
i ewentualne nadwyżki/niedobory redukować spacjami na końcu wiersza.

Obawiam się, że to już nie będzie justowanie. Justowanie to dokładne rozłożenie od lewej do prawej. Trzeba policzyć długość spacji w każdym wierszu, która przeważnie będzie liczbą zmiennoprzecinkową. Potem trzeba wstawiać spację po spacji, uwzględniając zaokrąglenie dla danej pozycji. Przykład:

średnia długość spacji: 1.7px
licznik: 1.7
SPACJA 1: 2px
licznik: 3.4
3.4 - 2 = 1.4
SPACJA 2: 1px
licznik: 5.1
5.1 - 3 = 2.1
SPACJA 3: 2px
licznik: 6.8
6.8 - 5 = 1.8
SPACJA 4: 2px
itd.
Go to the top of the page
+Quote Post
Gray
post
Post #20





Grupa: Zarejestrowani
Postów: 127
Pomógł: 0
Dołączył: 5.04.2010

Ostrzeżenie: (10%)
X----


Nie bardzo rozumiem, poco liczyć długość wszystkich spacji w każdym wierszu (może to przez tą późną godzinę)? Nie łatwiej by było sprawdzać długość każdego wiersza w pixelach i te krótsze wiersze "wydłużać", wstawiając równomiernie spacje między wyrazami?
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 25.08.2025 - 01:31