incolonnare testo su immagine

Ciao

Questo script richiama i dati dal db (delle firme o messaggi) e li stampa su un'immagine con le librerie gd2:

$db = mysql_connect('localhost', 'root', '') or die(mysql_error());
@mysql_select_db('login4', $db) or die(mysql_error());

$query = "SELECT * FROM firme";
$result = mysql_query($query);
$tot=mysql_num_rows($result);

$ima = imagecreatefromjpeg("gia4.jpg");//prendo l'immagine
$textcol = imagecolorallocate($ima,0,0,0);//Prendo il colore nero per il testo
list($larg, $altez, $uno, $due) = getimagesize("gia4.jpg"); //Metto nelle variabili $larg e $altez la larghezza e l'altezza dell'immagine con l'array getimagesize()

$destra=10;
If ($tot>9) {$destra=100;} 
$gra=20;

while($rot = mysql_fetch_array($result)){
 $firma = $rot["scritta"];
 $car = $rot["type"];
if ($car=="Times New Roman"){$font='times.ttf';}
elseif ($car=="Comic Sans MS"){$font='comicbd.ttf';}
elseif ($car=="Monotype Corsiva"){$font='MTCORSVA.TTF';}

imagettftext($ima,15,0,$destra,$gra,$textcol,$font, $firma);
$gra += 22;
}
echo $gra;
imagepng($ima,"nuova.png");//trasformo, per comodità mia, l'immagine in nuova.png e la scrivo
echo "<img src=\"nuova.png\">";
imagedestroy($ima);

viene stampato testo anche con caratteri diversi.

Il problema che mi sono trovato ad affrontare è quello di incolonnare il testo richiamato.

Vorrei stampare le firme su 3 o 4 colonne.

Con la prima colonna non ho avuto problemi. Stampo il testo e aumento il valore della variabile $gra che in pratica crea lo spazio tra un testo e il successivo, però non vorrei stampare + di 9 testi per colonna (in questo caso per esempio). Ho notato che è il quarto valore della funzione imagettftext a controllare questo posizionamento e ho provato a cambiare la variabile come potete vedere sopra.; ma ovviamente non è la soluzione corretta :P (tutta la prima colonna non fa altro che spostarsi del valore indicato e non, come avrei voluto, stampare dal  testo N. 10 in poi su un' altra colonna più a destra).

Potete aiutarmi?

Grazie

ps: spero di essere stato chiaro

inviato 8 anni fa
frankphp
modificato 8 anni fa
X 0 X

ti indico a grandi linee come procedere:

- Nel ciclo while che usi per la fetch dei record del DB devi mettere un contatore $num_riga che si incrementa ad ogni iterazione, così saprai a che riga sei arrivato.

- Ad ogni iterazione devi calcolare la lunghezza dela stringa che hai stampato sulla foto, con imagettfbbox(). Se conservi in una variabile $max_len la lunghezza della stringa più lunga della colonna saprai quanto deve distare la colonna successiva da quella attuale, in modo che i testi non si sovrappongano.

- ad ogni iterazione controlla se $num_riga sia passato alle righe di una nuova colonna:

if($num_riga / $righe_per_colonna > 1) {

in tal caso resetta $num_riga, incrementa l'ascissa del testo di tanti pixel quanti ne indica la variabile $max_len e resetta tale variabile.

 :bye:

risposto 8 anni fa
Gianni Tomasicchio
X 0 X

ti indico a grandi linee come procedere:

- Nel ciclo while che usi per la fetch dei record del DB devi mettere un contatore $num_riga che si incrementa ad ogni iterazione, così saprai a che riga sei arrivato.

- Ad ogni iterazione devi calcolare la lunghezza dela stringa che hai stampato sulla foto, con imagettfbbox(). Se conservi in una variabile $max_len la lunghezza della stringa più lunga della colonna saprai quanto deve distare la colonna successiva da quella attuale, in modo che i testi non si sovrappongano.

- ad ogni iterazione controlla se $num_riga sia passato alle righe di una nuova colonna:

if($num_riga / $righe_per_colonna > 1) {

in tal caso resetta $num_riga, incrementa l'ascissa del testo di tanti pixel quanti ne indica la variabile $max_len e resetta tale variabile.

 :bye:

imagettfbox mi calcola la lunghezza del testo?

In questo modo un testo della prima colonna non va a sovrapporsi a quello della seconda?

E questo quello che intendi?

Se è così al momento non è un problema perchè già indico (e costringo) l'utente a inserire testo non superiore a tot caratteri. Però forse potrebbe ritornarmi utile sta cosa, ma l'affronterò in un secondo momento magari.

Quello che non ho capito è come passare alla seconda colonna facendo in modo che le 9 righe di testo rimangano al loro posto (e il testo N.10 e successivi stampati sulla seconda ad esempio).

La soluzione che proponi mi sembra simile alla mia (che non va bene).

Magari mi sbaglio.

Grazie e buon anno.

risposto 8 anni fa
frankphp
X 0 X

Il tuo approccio è sbagliato perché l'aumento dell'ascissa del testo viene fatto prima del ciclo while, quindi ha effetto su tutte le righe che mostrerai, e non solo su quelle della seconda colonna.

Io invece ti suggerivo di fare l'incremento dell'ascissa all'interno del ciclo, e solo quando ti accorgi che stai per mostrare una riga di una nuova colonna. Ovviamente dovrai anche decrementare l'ordinata del testo, in modo che la prima riga di ciascuna colonna appaia in alto.

qualcosa del genere:

$destra=10;
$gra=20;
$num_riga = 0;
$max_len = 0;

while($rot = mysql_fetch_array($result)){
 $num_riga++;
 $firma = $rot["scritta"];
 $car = $rot["type"];
if ($car=="Times New Roman"){$font='times.ttf';}
elseif ($car=="Comic Sans MS"){$font='comicbd.ttf';}
elseif ($car=="Monotype Corsiva"){$font='MTCORSVA.TTF';}

imagettftext($ima,15,0,$destra,$gra,$textcol,$font, $firma);

$txt_box = imagettfbbox  (15, 0, $font, $firma);
$txt_len = $txt_box[2] - $txt_box[0];
$max_len = $max_len < $txt_len ? $txt_len : $max_len;

if($num_riga / 10 >= 1) {
$num_riga = 0;
$gra=20;
$destra = $destra + $max_len + 5;
} else {
$gra += 22;
}
}

il codice l'ho scritto al volo quindi va controllato...

 :bye:

risposto 8 anni fa
Gianni Tomasicchio
X 0 X

Scritto al volo ma funzionante (magari fossi in grado io di scrivere codice al volo e che funzioni correttamente  ;))

Va bene.

Penso in linea di massima di avere capito il codice (anche se cicli o condizioni all'interno di altri cicli quando non l'ho scritto io il codice ho difficoltà a intenderlo bene..come avrai già da un pezzo capito non sono una cima ;D ;D in programmazione)

Comunque dovrei farti altre 2 domande:

1) $txt_box = imagettfbbox  (15, 0, $font, $firma); Questo crea un arryay..giusto?

ma nella riga successiva che valore c'è qui: $txt_box[0]? Cosa sottrai insomma.

2) Non ho provato ancora ma il codice funziona nello stesso modo se le colonne sono più di 2 (vorrei inserire una 40tina di firme più o meno)?

Grazie

risposto 8 anni fa
frankphp
X 0 X

1) imagettfbbox() restituisce un array con tutte le coordinate (X e Y) dei 4 vertici del rettangolo che contiene il testo. La sottrazione serve a calcolare la lunghezza del rettangolo: ascissa del vertice a destra - ascissa del vertice a sinistra.

2) Si, dovrebbe funzionare anche per più colonne.

 :bye:

risposto 8 anni fa
Gianni Tomasicchio
X 0 X

1) imagettfbbox() restituisce un array con tutte le coordinate (X e Y) dei 4 vertici del rettangolo che contiene il testo. La sottrazione serve a calcolare la lunghezza del rettangolo: ascissa del vertice a destra - ascissa del vertice a sinistra.

2) Si, dovrebbe funzionare anche per più colonne.

 :bye:

ok grazie, gentile come sempre.

Mi rileggo il codice per capirlo meglio.

Ciao

risposto 8 anni fa
frankphp
X 0 X
Effettua l'accesso o registrati per rispondere a questa domanda