Častým obsahem nejen osobních stránek jsou fotografie. A kolik je s nimi práce!
Nepoužijete-li nějaký speciální software, znamená příprava stránky několik časově
velmi náročných úkonů. Nejprve všechny obrázky zmenšit pro náhledy a pak vytvořit
HTML dokument, kde bude zobrazen každý náhled a na něm odkaz na velkou fotografii.
Jistě, existují na to programy, ale jak uvidíte, není třeba žádný z nich instalovat.
S pár řádky PHP kódu to dokážete vy sami!
V tomto díle bude naším úkolem vytvořit náhledy (často se setkáte s názvem
"thumbnails") fotografií a to - logicky - v celém adresáři najednou.
K tomu využijeme znalostí z dílu PHP
v praxi, 17. díl - Výpis adresáře. Kromě toho je třeba zapnout podporu práce
s obrázky. Pod Windows se to dělá jednoduše tak, že zeditujeme php.ini (ve složce
C:\Windows nebo C:\WINNT) a to následujícím způsobem:
1) Nastavíme extension_dir na adresář, kde máme soubor php_gd.dll. Obvykle to
bývá "c:\php\extensions\".
2) Odkomentujeme (odstraníme středník před) "extension=php_gd.dll".
Logická struktura PHP skriptu bude vypadat přibližně takto: Nejprve musí být
k dispozici HTML formulář, ve kterém zadáme umístění souborů, způsob změny jejich
velikosti (pevná velikost všech vzniklých náhledů nebo poměrná), jejich jména
a kvalitu výsledného jpegu. Samotný PHP skript pak musí načíst všechny soubory
v daném adresáři, vyřadit ty, s nimiž nechceme pracovat, a nakonec u těch správných
změnit velikost a uložit je do souborů.
Načtení souborů a jejich selekce:
$adresar_name=dirname($cesta)."/";
$adresar=opendir($adresar_name);
$j=0;
while ($soubor=readdir($adresar))
{
@$overeni=GetImageSize($adresar_name.$soubor);
if ($soubor!="."&&$soubor!=".."&&$overeni[2]==2)
{
$in_name[$j]=$adresar_name.$soubor;
$out_name[$j]=$adresar_name.$prefix.$soubor;
$j++;
}
elseif($soubor!="."&&$soubor!=".."&&(!$overeni||$overeni[2]!=2))
{
echo "Nelze pracovat se souborem: $soubor <br>";
}
}
closedir($adresar);
|
Z HTML formuláře získáme cestu ke konkrétnímu souboru. Z ní pomocí funkce dirname()
získáme jméno adresáře určeného ke zpracování. Ten pak již jednou probíraným
způsobem otevřeme a cyklem while() z něj získáme všechny soubory. Novinkou je
použití funkce GetImageSize().
Předáváme jí celou cestu k dotyčnému souboru a ona zjistí hned několik věcí
- šířku, výšku a typ obrázku - a vrátí je jako pole. K jednotlivým informacím
se pak přistupuje přes indexy. $overeni[] je tedy pole s těmito informacemi
a použitím indexu 2 se dozvíme, zda se jedná o jpeg (1 = GIF, 2 = JPG, 3 = PNG,
4 = SWF, 5 = PSD, 6 = BMP). Pracovat se soubory tedy budeme jedině v případě,
že $overeni[2]==2. Proč je před $overeni[] zavináč? Ten zakazuje výpis chybové
hlášky. My totiž GetImageSize() využíváme též k tomu, aby nám sdělila, zda se
vůbec o obrazový soubor jedná. V případě, že nikoliv, nastane chyba. To ověřujeme
v druhé podmínce - (!$overeni||$overeni[2]!=2) - tzn. když $overeni[] vůbec
neexistuje nebo soubor není jpeg, vypíše se "Nelze pracovat se souborem...".
Tímto jsme vybrali jen a pouze jpeg soubory a jejich jména dosadíme do polí
$in_name[] a $out_name[]. Pole $out_name[] se liší v tom, že soubor se jmenuje
podle zadání jinak - např. fotka má název "foto.jpg" ($in_name[])
a náhled bude "t_foto.jpg" ($out_name[]).
Získání konkrétních názvů souborů bylo cílem této části skiptu. Samotné jejich
zpracování je cílem části následující:
for($i=0;$i<count($in_name);$i++)
{
$in_size=GetImageSize($in_name[$i]);
if($velikost=="pevna")
{
if($prevratit=="ano"&&$in_size[0]<$in_size[1])
{
$x=$p_y;
$y=$p_x;
}
else
{
$x=$p_x;
$y=$p_y;
}
}
elseif($velikost=="pomerna")
{
$x=$pomer*$in_size[0] /100;
$y=$pomer*$in_size[1] /100;
}
$out_size=array($x,$y);
$in=ImageCreateFromJPEG($in_name[$i]);
$out=ImageCreate($out_size[0],$out_size[1]);
ImageCopyResized($out,$in,0,0,0,0,$out_size[0],
$out_size[1],$in_size[0],$in_size[1]);
ImageJpeg($out,$out_name[$i],$out_q);
ImageDestroy($in);
ImageDestroy($out);
}
|
Kromě názvů potřebujeme také znát (vstupní) velikosti fotek a (výstupní) velikosti
náhledů. Pole $in_size[] získá funkcí GetImageSize pod indexem 0 a 1 šířku a
výšku fotek. Pomocí informací z formuláře a vstupních rozměrů vypočítáme výslednou
velikost náhledů. V prvém případě - velikosti pevné - provedeme ještě větvení
podmínek podle orientace fotek. Nevypadalo by dobře, kdyby i fotky na výšku
byly zmenšené stejně jako fotky na šířku (v případě, že nechcete náhledy jako
čtverce, samozřejmě ;) . Proto se zjišťuje, zda-li bylo ve formuláři zaškrtnuto
převracení a dále se ověří, jestli je šířka fotky menší než její výška. Poměrná
velikost se spočítá jednoduše z původních velikostí (jako procenta). Výsledek
se dosadí do pole $out_size[].
Nyní přistupme již k samotné tvorbě obrázků. Funkcí ImageCreateFromJPEG()
vytvoříme v proměnné $in obsah obrázku načteného ze souboru určeného polem $in_name[].
Výstupní obrázek - zatím virtuálně - vytvoříme v proměnné $out funkcí ImageCreate()
s parametry velikosti v poli $out_size[]. Následující funkcí ImageCopyResized()
provedeme tolik očekávanou operaci změny velikosti původního obrázku a jeho
kopii do obrázku v $out. Z virtuálního obrázku se stane skutečný soubor funkcí
ImageJpeg(),
jejímiž parametry jsou kromě obrázku také jméno souboru náhledu a kvalita výsledného
jpegu (zadá se také přes formulář). Nakonec po sobě "uklidíme" standardním
způsobem pomocí ImageDestroy().
Celá naše aplikace včetně formuláře a pár dalších drobností bude vypadat následovně:
<html>
<body>
<h1>Náhledy - Resizer</h1>
<?
if(!isset($submit)||empty($cesta)){
?>
<form action="<?= $PHP_SELF ?>" method="get">
<table width="400" border="0" cellpadding="5">
<tr>
<td>Cesta k adresáři: </td>
<td colspan="2">
<input type="file" name="cesta">
</td>
</tr>
<tr>
<td>Velikost: </td>
<td>šířka</td>
<td>výška</td>
</tr>
<tr>
<td>
<input type="radio" name="velikost" value="pevna" checked>
Pevná:</td>
<td>
<input type="text" name="p_x" value="150" size="5">
px</td>
<td>
<input type="text" name="p_y" value="100" size="5">
px</td>
</tr>
<tr>
<td> </td>
<td colspan="2">
<input type="checkbox" name="prevratit" value="ano" checked>
Převrátit podle orientace fotografie</td>
</tr>
<tr>
<td>
<input type="radio" name="velikost" value="pomerna">
Poměrná: </td>
<td colspan="2">
<input type="text" name="pomer" value="25" size="5">
% </td>
</tr>
<tr>
<td>Prefix náhledů:</td>
<td colspan="2">
<input type="text" name="prefix" value="t_" size="5">
</td>
</tr>
<tr>
<td>Kvalita (jpg):</td>
<td colspan="2">
<input type="text" name="q" value="75" size="5">
%</td>
</tr>
</table>
<br>
<input type="submit" name="submit" value="Start">
<input type="reset" name="reset" value="Reset">
</form>
<?
}else{
if($q>0||$q<=100)
{
$out_q=$q;
}
else
{
$out_q="75";
}
$adresar_name=dirname($cesta)."/";
$adresar=opendir($adresar_name);
$j=0;
while ($soubor=readdir($adresar))
{
@$overeni=GetImageSize($adresar_name.$soubor);
if ($soubor!="."&&$soubor!=".."&&$overeni[2]==2)
{
$in_name[$j]=$adresar_name.$soubor;
$out_name[$j]=$adresar_name.$prefix.$soubor;
$j++;
}
elseif($soubor!="."&&$soubor!=".."&&(!$overeni||$overeni[2]!=2))
{
echo "Nelze pracovat se souborem: $soubor <br>";
}
}
closedir($adresar);
for($i=0;$i<count($in_name);$i++)
{
$in_size=GetImageSize($in_name[$i]);
if($velikost=="pevna")
{
if($prevratit=="ano"&&$in_size[0]<$in_size[1])
{
$x=$p_y;
$y=$p_x;
}
else
{
$x=$p_x;
$y=$p_y;
}
}
elseif($velikost=="pomerna")
{
$x=$pomer*$in_size[0] /100;
$y=$pomer*$in_size[1] /100;
}
$out_size=array($x,$y);
$in=ImageCreateFromJPEG($in_name[$i]);
$out=ImageCreate($out_size[0],$out_size[1]);
ImageCopyResized($out,$in,0,0,0,0,$out_size[0],
$out_size[1],$in_size[0],$in_size[1]);
ImageJpeg($out,$out_name[$i],$out_q);
ImageDestroy($in);
ImageDestroy($out);
}
echo '<h2>Hotovo</h2><a href="'.$PHP_SELF.'">Návrat</a>';
}
?>
</body>
</html>
|
Ve formuláři používáme proměnnou $PHP_SELF, ta vždy ukrývá název konkrétního
souboru (PHP skriptu), takže při jeho přejmenování nemusíte měnit odkazy. Kvalita
výsledného jpegu se kontroluje, aby byla mezi 0 a 100. Jinak je vše předpokládám
jasné.
Vidíte - stačí nám soubor menší než tři kilobajty na výsledek srovnatelný s
mnohdy drahým softwarem. Pravda, je stále co vylepšovat, o tom není pochyb,
ale na tvorbu jednoduchým náhledů to bohatě stačí. Sami můžete prozkoumat další
PHP funkce týkající se obrázků, možností je mnoho - třeba přidat přímo do každého
obrázku nějaký popisek (oblíbené je např. jméno fotografa či serveru). Příště
se podíváme, jak jednoduše vygenerovat stránku plnou náhledů.
Veselý Jan
|