Grafika publishing webtip.cz grafika.cz mujiPod.cz mujmac.cz fotografovani.cz printing.cz builder.cz galerie
webtip.cz
adresář  | práce  | diskuse  | redakce  | inzerce
 
 


  PHP v praxi, 22. díl - Vytvoření zmenšených obrázků
o autorovi 
poslat mailem 
tisknout článek 
aktuální rubrika 
Ulehčete si práci s tvorbou náhledů. Pomocí PHP skriptu vytvoříme náhledy z celého adresáře najednou a to velmi snadno.

Veselý Jan - 01.03.2002 - tutorial - Rubrika: PHP
Předchozí díl: PHP v praxi, 21. díl - soubor.php?jak=na&t=o
Seriál: 
Následující díl: PHP v praxi, 23. díl - Tvorba fotoalba

Č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>&nbsp; </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


Hodnocení článku: -1- -2- -3- -4- -5-  Aktuální hodnocení: 2.74 (2990)

Relevantní články
Žádné články


Příspěvky do diskuse o aktuálním článku
Petr Havel17.09.16:42Poměrná změna
80rac3k22.11.20:20problém s "imagejpeg"
80rac3k23.11.19:03RE: problém s
michňas14.06.23:04pro ty co chtějí tu mám vytvoření malého náhledu zjednodušeně
Robinek22.10.0:42problem s obrazky
Petr Kněžek01.08.20:21Uložení do databáze
Milo08.03.12:05dotaz
Tin01.06.13:02Hnus barvy
Yenowicz22.08.12:35RE: Hnus barvy
Yenowicz22.08.12:38RE: RE: Hnus barvy - ŘEŠENÍ
croow24.07.14:59stejny problem s php.ini
Ondřej Hamák21.03.18:17imagecreatefromjpeg()
Jan Veselý21.03.22:06RE: imagecreatefromjpeg()
Lukii03.04.1:04RE: imagecreatefromjpeg()
Martin30.07.21:18RE: imagecreatefromjpeg()
Jan03.03.23:28A co ACDSee
Jan Vesely05.03.17:15RE: A co ACDSee
Tomas01.03.23:07neni to zbytecne?
Jan Vesely05.03.17:13RE: neni to zbytecne?
YaGi01.03.17:05Kvalita
Jan Vesely05.03.17:08RE: Kvalita
Laki24.06.15:18RE: Kvalita
Gugma02.01.11:27RE: RE: Kvalita
  

 

  O vydavateli | Kontakt | Ceník reklamy | Ochrana osobních dat
©2002 Grafika Publishing. Všechna práva vyhrazena!