Newsgroup: it.comp.www.php
Titolo: gd, db e gestione delle immagini

...è solo una curiosità, non è un problema!
molti, come filosofia, gestiscono le immagini su db come un campo al cui 
interno è definito il path dell'immagine su disco.
questo ha i suoi chiarissimi pregi e difetti, tra cui (pregio) il fatto di 
poter definire nel codice html: <img src='path_da_db.jpg'>
sapendo che è possibile scrivere uno script con header image/jpeg che 
ritorna l'image stream direttamente sul browser, posso pensare di gestire 
anche immagini "usa e getta" (es, reportistiche, grafici ecc..)
è però possibile anche inserire immagini come blob nel db.
questo, senza pensarci troppo, mi ha sempre fatto credere che facendo così 
fosse necessario creare files fisici su disco temporanei per farli leggere 
dal browser. però è una cazzata: si impegnano troppe risorse!
secondo voi, è pesante come soluzione pensare di inserire nel db le 
immagini e, per richiamarle, inserire:
<img src='script.php?parametri=...'>
dove script.php mi prende il campo blob da db e me lo ritorna come 
imagestream con l'appropriato header??
ovvero:
la lettura su db e la creazione dello stream con il browser, perde molto di 
prestazioni rispetto alla lettura del file fisico?
secondo voi non è conveniente considerando anche i pregi che ha una 
gestione pulita delle immagini tramite db?
ci sono altri metodi secondo voi + semplici per visualizzare immagini in 
una pagina prese da campi blob?
ciao

prestazioni rispetto alla lettura del file fisico?
Usualmente, si evita di utilizzare blob nel database, non per
chiarezza sintattica oppure per avere prestazioni migliori nel
recupero della singola immagine, ma per non appesantire l'*intero*
database.
hola
Buttha

 prestazioni rispetto alla lettura del file fisico?
non penso proprio:
Esempio di apertura file su un disco rigido (molto schematico, ci sono
sistemi lenti e veloci, implementazioni vari, ma giusto per chiarire cmq.
che cosa succede quando si legge un file in un sistema classico):
1) determinare cartella sul quale voglio leggere la directory (read/cache
del cluster + entry nel fat [di solito nel cache]), questo per ogni
sottodirectory nel path. Questo cmq. per un path come /home/chissachi ci
saranno un paio di read per determinare i cluster dove si trovano le
directory (moltiplicato per numero di cartelle).
2) cercare il file nella cartella read=clustersize/direntrysize (se sono
tanti file diventa molto lungo: esempio dos: per ogni settore (512) file
nomi corti sono 32, quindi ogni 16 file nuovo read dal HD del dir (+fat)
(oppure cache, in teoria meno perche' si cachano cluster). Quando hai 1600
immagini fai in media 50 accessi al disco... Se usi nomi lunghi come minimo
il doppio (parlo di FAT32)...
3) una volta determinato il cluster in quale esiste il file si puo'
leggerlo...
4) via il server vengono mandati i dati
database (con Btree)
1) leggere l'index  (cached in memoria se usato molto). Ricerca bsearch sul
index (tempo medio e log[t](n)*C (t numero dei fogli per pagina) e non
(n/2)*C rispetto ad un directory comune (AFAIK, corregetemi se non mi
ricordo bene).
2) l'index indica direttamente al dato da caricare (volendo, ma dipende
dalla implementazione del Btree)..., quindi apertura della tabella in
questione con un seek alla posizione del dato (il file).
3) via il server vengono mandati i dati
Direi cosi: dipendente dal tipo Filesystem e dalla quantita' dei file in una
cartella il database puo' essere piu' efficiente (ma non e' la regola).
Bisogna stare attento ad indicizzare bene il database (senza indice diventa
molto lento).
Se cambi Server/OS/FS/PC, cambia anche la prestazione. E quindi non guardare
troppo la parte technica/efficienza ed andrei sempre con una soluzione
pulita...

 directory (moltiplicato per numero di cartelle).
Straordinario: se mi avanzeranno una vita o due oltre a quella attualmente
in corso imparerò certamente cosa significa tutto questo ;-)))
:) Roberto

 ha scritto nel messaggio
news:B8455534.5DE8%ro...@tiscalinet.it...

già, tutto perfettamente chiaro :-)))
cmq secondo me tirare fuori l'immagine da DB è più lento, puo' darsi che mi
sbagli, ma basterebbe un test...
Ciao
Alex

"Alessio" <(
alessi...@libero.it
)@NOSPAM.tld> wrote in
news:_2RT7.16914$
o9.6...@news1.tin.it
: 

ho capito, và!! provo a fare un test io e qui, prossimamente, vi mando 
l'output....
...non so quanto ci metterò!
ciao

 ...non so quanto ci metterò!
...infatti ho già incontrato un problema:
le funzioni gd: int imagecreatefromjpeg(string string)
prendono in input solo il nome di un file!!!
se io ho una variabile con dentro il contenuto di un file (pescato da db)
come faccio? 
ho provato a pare una print della variabile ma niente...
ho provato a fare così:
(con e senza header)
header ("Content-type: image/jpeg");
$fd=fopen("php://stdout",'a');
fwrite($fd, $riga[0]);
fclose($fd);
ma mi dice: 
<b>Warning</b>:  fopen("php://stdout","a") - No error in
<b>d:\share\manuali\sito\mypages\prove\drawing\get.php</b> on line
<b>17</b><br> 
cioè: no error!!
non ci sono errori ma mi interrompe l'esecuzione dello script???
mah!!
qualcuno sa dirmi come fare??
non mi dite di creare un file temporaneo perché è proprio quello che voglio 
evitare!!
ciao

 wrote in message
news:B8455534.5DE8%ro...@tiscalinet.it...

L'unica cosa forse interessante da imparare (in questa vita) sono i Btree,
il resto non serve molto...

"Alessio" <(
alessi...@libero.it
)@NOSPAM.tld> wrote in message
news:_2RT7.16914$o9.6...@news1.tin.it...

Hmmm, potrebbe essere interessante di fare un bench. Quando ho tempo metto
su qualcosa e lo facciamo girare in vari ambienti (linux/win/solaris
apache/iis) ...

 wrote in message
news:B8455534.5DE8%ro...@tiscalinet.it...

Una cosa che non ho sottolineato in tutto questo (mettiamo i piedi in
terra)...
Avere dati in un database puo' avere molto senso in sistemi di rete in cui
si usano server dedicati ai vari lavori. A volte e meglio distribuire un
sistema e quindi e' molto piu' facile mettere i dati in un database ai quali
puoi acceddere in remoto via query perche' le macchine (i Firewall) non
vengono configurate per poter trasmettere direttamente dei dati.
L'infrastruttura in questo caso determina molto la soluzione.

 
mi sono incappato in un grosso problema... vedi post 18315...
ho provato inoltre ad usare imagecreatefromstring(non documentata) ma poi 
ho visto dai sorgenti di php che non è altro che una traduzione per le 
funzioni gd di imagecreatefromjpegctx()... che vogliono comunque un FILE*!!
magari tu mi sai rispondere... mi sembri il + scafato di tutti in questa 
gabbia di matti!
:-)
ciao


Non mi e' chiaro il problema. Ma vediamo! Se tu hai i dati di un immagine
nel database e lo tiri fuori li devi soltanto passare cosi come sono al
browser (e mandi solo il header per dire al browser che tipo di dati si deve
aspettare). Questo discorso vale per qualsiasi tipo di documento salvato in
un DB (ad esempio un sistema cercalavoro che salva dei CV in un database [si
aspettano PDF,DOC,TXT (ho visto pure un .SWF)]). Nel tuo caso devi sapere
che tipo di immagine e' (GIF,JPG)...
showImage.php:
<?php
// apri database,
// query
// dati binari (Attenzione ai slash, virgolette ed animali vari) sono in
$dati
header ("Content-type: image/gif"); // mettiamo un GIF?
echo $dati;
?>
la pagina per visualizzare questo dato dovrebbe/potrebbe contenere solo il
tag img:
show.html:
<IMG src=showImage.php?eventualiParametriPerLaQuery=123>

 (GIF,JPG)... 
chiedo umilmente venia...
un debug un filo più accurato ha dimostrato la mia scemenza globale 
totale!!
in realtà, la print della variabile contenente l'immagine funziona 
perfettamente.
l'errore (scemo io che non ho controllato prima) stava nel caricamento 
delle immagini su db:
while($filename=readdir($dir))
	{
	$type=substr($filename,strlen($filename)-4);
	if($type=='.jpg')
		{
		print $filename."<br>";
		$fd = fopen ($filename, "r");
		$contents = fread ($fd, filesize ($filename));
		fclose ($fd);
		print strlen($contents)."<br>";
		$sql="insert into pippo (campoblob) values 
('".addslashes($contents)."')";
		mysql_query($sql,$conn);
		$sql="insert into pluto (path) values ('$filename')";
		mysql_query($sql,$conn);
		}
	}
lo vedi subito tu l'errore??
beh, con altre immagini (.gif) ha sempre funzionato. poi ho realizzato che 
la dimensione dei campi blob non coincideva a quella dei files...
dovevo semplicemente aprire il file in "rb", essendo su Windows!!!
quando programmavo in C su DOS non mi succedeva, ero abituato!
adesso che vago tra php, linux, e vari linguaggi mi sono un po' perso!
cazzarola!!
grazie, comunque.
ciao!!

gestione pulita delle immagini tramite db?
No. Del resto io in genere uso una directory separata per le immagini, e le
immagini sono proprio richiamate tramite script PHP, non con il loro nome.
Usando readfile(), il risultato e' abbastanza efficiente, anche se e' circa
il 30% piu' lento che usando SRC="image.jpg".
E posso decidere quali immagini dichiarare statiche, quali non far cachare,
e cosi' via.
Leonardo
-- 
And where the black and corkscrew towers climb
Lost and athirst the ragged pack abides,
Old as the aeons, trapped in tombs of time,
Sailing the tortuous temporal tides...

 non penso proprio:
Non conosco bene il funzionamento della  FAT ma, come dici giustamente
alla fine, dipende dal fs, dall'OS e da un sacco di altre cose.
Considera pero` una cosa: se metti le immagini nel db le dovrai leggere
una alla volta con uno script php, quindi per ogni immagine viene
richiamato l'interprete php, che legge dal disco (o dalla cache) lo
script, lo interpreta, apre il db, fa la ricerca e manda il risultato
al browser. Quindi n+1 partenze dell'interprete, n accessi al db, n
ricerche e n visualizzazioni. In totale 4n+1 (in linea di massima)
Con un unico script che scrive <img src... hai l'interprete caricato
una sola volta, un singolo accesso al db, una singola ricerca e n
letture di risultati. Poi avrai n accessi al webserver per le immagini,
ma li avrai comunque, e n accessi del server al disco per mandare
l'immagine al client. Totale: 2n+1
Poi, siccome le n non hanno tutte peso uguale andrebbe calibrato il tutto.
:)
Bye.